#include "experimentresultui.h"
#include "ui_experimentresultui.h"
#include "YuzhiLineEdit.h"



ExperimentResultUi::ExperimentResultUi(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::ExperimentResultUi)
{
    ui->setupUi(this);



    ui->resultTable->setContextMenuPolicy(Qt::CustomContextMenu);

    /* 初始化 */
    cusMsg = new CustomMessageBox();
    pTool = new PrintTool();
    dAlys = new dataanalyse();
    dyeLibrary = new DyeLibrary();

    autoExportFlag = false; // 自动导出标识位（默认开启自动导出）
    isGuiYi = 0; // 默认归一化关闭
    isDeltaRn = 1; // 默认是deltaRn
    resultYAxisMax = 0; // 记录y轴最大值
    resultYAxisMin = 0; // 记录y轴最小值
    isChartInit = true; // 默认为图表的初始状态
    updateCurveData = false; // 默认不更新曲线信息

    yuZhiHash = initYuZhi(yuZhiHash); // 阈值Hash初始化

    // 基线数组初始化(默认写死4个)
    for(int i = 0; i < 4; i++){
        QHash<QString, int> baseLine;
        baseLine.insert("start", 3);
        baseLine.insert("end", 15);
        this->baseLineList.append(baseLine);
    }

    this->firstInitAlysTar = true; // 第一次初始化分析靶基因状态为true

    /* 取消列表反应板编辑 */
    ui->resultDetailTable->setEditTriggers(QAbstractItemView::NoEditTriggers);

    /* 隐藏组件 */
    ui->exitFullscreen->hide();
    ui->exitTableFullscreen->hide();
    ui->resultDetailTable->hideColumn(6); // 隐藏第六列id列

    /* 列表排序 */
    ui->resultDetailTable->setSortingEnabled(true);

    /* 右键功能 */
    tableMenu = new QMenu(ui->resultTable);
    action_print = new QAction("打印", this);
    action_export = new QAction("导出excel", this);

    tableMenu->addAction(action_print);
    tableMenu->addAction(action_export);

    /* 结果 */
    xSeries = -1;
    yAxisMaximum = 8000;
    initYAxisMaxmum = 8000;
    logarithmYMaxiMum = 5000; // 最大对数y轴数据: 10000
    /* 隐藏组件 */
    ui->resultRestore->hide();

    /* 图例初始化 */
    // 曲线：默认都可见
    this->cy5Visible = true;
    this->famVisible = true;
    this->vicVisible = true;
    this->roxVisible = true;

    /* 创建结果页面图表 */
    this->createResultChart();

    ui->resultTable->verticalHeader()->setDefaultSectionSize(48);
    ui->resultTable->setVerticalHeaderLabels(QStringList() << "A" << "B" << "C" << "D" << "E" << "F" << "G" << "H");
    // 表格自适应宽度
    ui->resultTable->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch);
    ui->resultTable->horizontalHeader()->setDefaultAlignment(Qt::AlignCenter);
    ui->resultTable->verticalHeader()->setDefaultAlignment(Qt::AlignCenter);
    ui->resultTable->horizontalHeader()->setStyleSheet("QHeaderView::section{border:1px solid #000;border-top:none;border-left:none;height:32px;background:transparent;font-family:\"Alibaba PuHuiTi\";text-align:center;}");
    ui->resultTable->verticalHeader()->setStyleSheet("QHeaderView::section{border:1px solid #000;border-top:none;border-left:none;width:23px;background:transparent;font-family:\"Alibaba PuHuiTi\";text-align:center;}");
    ui->resultDetailTable->horizontalHeader()->setDefaultAlignment(Qt::AlignCenter);
    ui->resultDetailTable->verticalHeader()->setDefaultAlignment(Qt::AlignCenter);
    ui->resultDetailTable->horizontalHeader()->setStyleSheet("QHeaderView::section{border:1px solid #000;border-top:none;border-left:none;height:32px;background:transparent;font-family:\"Alibaba PuHuiTi\";text-align:center;}");
    ui->resultDetailTable->verticalHeader()->setStyleSheet("QHeaderView::section{border:1px solid #000;border-top:none;border-left:none;width:23px;background:transparent;font-family:\"Alibaba PuHuiTi\";text-align:center;}");

    // 详情表格只能选中一行
    ui->resultDetailTable->setSelectionBehavior(QAbstractItemView::SelectRows);

    /* 查看过滤按钮 */
    menu = new QMenu();
    action_1 = new QAction(tr("&样本名"));
    action_3 = new QAction(tr("&靶基因"));
    action_2 = new QAction(tr("&QC标识"));
    action_1->setCheckable(true);
    action_3->setCheckable(true);
    action_2->setCheckable(true);
    action_1->setChecked(true);
    action_3->setChecked(true);
    action_2->setChecked(true);
    menu->addAction(action_1);
    menu->addAction(action_3);
    menu->addAction(action_2);
    /* QMenu样式 */
    menu->setStyleSheet("QMenu::item{"
                        "width: 107px;"
                        "font-size: 20px;"
                        "font-family: 'Alibaba PuHuiTi';"
                        "padding: 5px;"
                        "}"
                        "QMenu::item::selected {"
                        "color: #000;"
                        "border: none;"
                        "background: rgba(75, 154, 250, 0.2);"
                        "}");
    ui->tableFilter->setMenu(menu);

    ui->resultTable->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch);
    ui->resultTable->verticalHeader()->setSectionResizeMode(QHeaderView::Stretch);
    //    ui->resultTable->verticalHeader()->setDefaultSectionSize(48);
    ui->resultDetailTable->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch);
    ui->resultDetailTable->verticalHeader()->setSectionResizeMode(QHeaderView::Stretch);


//    connect(this->resultChart->ccView, &CustomChartView::chartViewDoubleClick, this->yuZhiLabelHash["fam"], &YuzhiLineEdit::onEditingFinished);

    /* 反应板全屏按钮 */
    connect(ui->tableFullscreen, &QPushButton::clicked, this, [=](){
        /* 屏蔽组件 */
        ui->tableFilter->hide();
        ui->tableFullscreen->hide();
        /* 退出全屏组件生效 */
        ui->exitTableFullscreen->show();
        /* 全屏 */
        ui->resultRight->setWindowFlags(Qt::Window);
        ui->resultRight->showFullScreen();
    });

    /* 反应板退出全屏 */
    connect(ui->exitTableFullscreen, &QPushButton::clicked, this, [=](){
        /* 屏蔽组件 */
        ui->exitTableFullscreen->hide();
        /* 组件生效 */
        ui->tableFilter->show();
        ui->tableFullscreen->show();
        /* 退出全屏 */
        ui->resultRight->setWindowFlags(Qt::Widget);
        ui->resultRight->showNormal();
    });

    /* 点击右扩展按钮 */
    connect(ui->resultRightExpending, &QPushButton::clicked, this, [=](){
        ui->resultLeft->hide();
        ui->resultRight->show();
        ui->resultRestore->show();
        ui->resultRightExpending->hide();
        ui->resultLeftExpending->show();
    });

    /* 点击左扩展按钮 */
    connect(ui->resultLeftExpending, &QPushButton::clicked, this, [=](){
        ui->resultLeft->show();
        ui->resultRight->hide();
        ui->resultRestore->show();
        ui->resultRightExpending->show();
        ui->resultLeftExpending->hide();
        ui->resultGraphicsView->update(); //刷新曲线所在内容区
    });

    /* 点击还原按钮 */
    connect(ui->resultRestore, &QPushButton::clicked, this, [=](){
        ui->resultLeft->show();
        ui->resultRight->show();
        ui->resultRestore->hide();
        ui->resultRightExpending->show();
        ui->resultLeftExpending->show();
        ui->resultGraphicsView->update(); //刷新曲线所在内容区
    });

    /* 运行曲线全屏 */
    connect(ui->curveFullscreen, &QPushButton::clicked, this, [=](){
        /* 隐藏组件 */
        ui->curveFullscreen->hide();
        ui->curvePrint->hide();
        ui->curveSave->hide();
        /* 显示还原组件 */
        ui->exitFullscreen->show();
        /* 全屏 */
        ui->resultLeft->setWindowFlags(Qt::Window);
        ui->resultLeft->showFullScreen();
    });

    /* 运行曲线退出全屏 */
    connect(ui->exitFullscreen, &QPushButton::clicked, this, [=](){
        /* 隐藏组件 */
        ui->curveFullscreen->show();
        ui->curvePrint->show();
        ui->curveSave->show();
        /* 显示还原组件 */
        ui->exitFullscreen->hide();
        /* 全屏 */
        ui->resultLeft->setWindowFlags(Qt::SubWindow);
        ui->resultLeft->showNormal();
    });

    /* 打印曲线 */
    connect(ui->curvePrint, &QPushButton::clicked, this, [=](){
        QPixmap pix = QPixmap::grabWidget(ui->paintCurve);
        pTool->printEvent(pix, this);
    });

    /* 保存曲线 */
    connect(ui->curveSave, &QPushButton::clicked, this, [=](){
        QString completeDir = QFileDialog::getExistingDirectory(
                    this,
                    "保存图片",
                    "./");
        if(completeDir != ""){
            QString filePath = completeDir + "/" + experiment.experiment_id + "_" + experiment.experiment_name + " resultCurve.png";
            QPixmap pixmap(ui->paintCurve->size());
            pixmap.fill(Qt::transparent);
            ui->paintCurve->render(&pixmap);
            if(!pixmap.save(filePath, "PNG"))
                cusMsg->show(this, CMsg::CCritical, "曲线图片保存", "图片保存失败");
            else
                cusMsg->show(this, CMsg::CInformation, "曲线图片保存", "图片保存成功");
        }
    });

    /* 曲线过滤 */
    connect(ui->channalSelection, &QComboBox::currentTextChanged, this, &ExperimentResultUi::curveFilter);

    /* 点击图例，隐藏对应曲线 */
    // 绑定信号槽函数
    connect(this, &ExperimentResultUi::sigCurveLabelFilter, this, &ExperimentResultUi::curveLabelFilter);
    /* fam */
    connect(ui->famBtn, &QPushButton::clicked, this, [=](){
        emit ExperimentResultUi::sigCurveLabelFilter("1");
    });
    connect(ui->famLabel, &QPushButton::clicked, this, [=](){
        emit ExperimentResultUi::sigCurveLabelFilter("1");
    });

    /* vic */
    connect(ui->vicBtn, &QPushButton::clicked, this, [=](){
        emit ExperimentResultUi::sigCurveLabelFilter("2");
    });
    connect(ui->vicLabel, &QPushButton::clicked, this, [=](){
        emit ExperimentResultUi::sigCurveLabelFilter("2");
    });

    /* rox */
    connect(ui->roxBtn, &QPushButton::clicked, this, [=](){
        emit ExperimentResultUi::sigCurveLabelFilter("3");
    });
    connect(ui->roxLabel, &QPushButton::clicked, this, [=](){
        emit ExperimentResultUi::sigCurveLabelFilter("3");
    });

    /* cy5 */
    connect(ui->cy5Btn, &QPushButton::clicked, this, [=](){
        emit ExperimentResultUi::sigCurveLabelFilter("4");
    });
    connect(ui->cy5Label, &QPushButton::clicked, this, [=](){
        emit ExperimentResultUi::sigCurveLabelFilter("4");
    });

    /* 对数图 */
    connect(ui->logarithm, &QCheckBox::toggled, this, [=](bool islogarithm){
        if(islogarithm){
            /* 渲染对数图 */
            this->logarithmCurve();
        }
        else {
            /* 渲染扩增曲线 */
            this->renderResultCurve();
        }
    });

    /* 上一步按钮 */
    connect(ui->previousBtn, &QPushButton::clicked, this, [=](){
        emit ExperimentResultUi::previousEvent();
    });

    /* 下一步按钮 */
    connect(ui->nextBtn, &QPushButton::clicked, this, &ExperimentResultUi::nextCallback);

    /* 保存按钮 */
    connect(ui->saveBtn, &QPushButton::clicked, this, [=](){
        emit ExperimentResultUi::saveEvent();
    });

    connect(ui->resultTable, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(slot_DL_RcOnTw(QPoint)));
    connect(action_print, &QAction::triggered, this, &ExperimentResultUi::slotActionSave);
    connect(action_export, &QAction::triggered, this, &ExperimentResultUi::slotActionExport);


    /* 点击反应孔，对应曲线显示 */
    ui->resultTable->setMouseTracking(true);
    connect(ui->resultTable, &QTableWidget::itemSelectionChanged, this, &ExperimentResultUi::filterSelectedCurve);

    /* 点击详细表，对应曲线加粗 */
    ui->resultDetailTable->setMouseTracking(true);
    connect(ui->resultDetailTable, &QTableWidget::itemSelectionChanged, this, &ExperimentResultUi::boldCurve);

    /* 点击详情表，对应曲线取消加粗 */
    connect(ui->resultDetailTable, &QTableWidget::doubleClicked, this, &ExperimentResultUi::unboldCurve);

    /* 样板表过滤功能 */
    connect(ui->tableFilter, SIGNAL(triggered(QAction*)), this, SLOT(filter(QAction*)));
    connect(ui->resultTable, SIGNAL(entered(QModelIndex)), this, SLOT(ShowTooltip(QModelIndex)));

    /* 选中反应版，改变item颜色 */
    connect(this, &ExperimentResultUi::changeRpItemBgColor, this, &ExperimentResultUi::tableClick);

    /* 重新数据分析按钮 */
    connect(ui->analysisBtn, &QPushButton::clicked, this, [=](){
        updateCurveData = true; // 更新曲线信息
        if(ui->logarithm->checkState() == Qt::Checked){ // 选中对数图
            this->logarithmCurve();
        }else { // 普通曲线
            this->renderResultCurve();
        }
    });

    /* 阈值线颜色过滤 */
    connect(ui->colorMarked, &QComboBox::currentTextChanged, this, [=](){
        if(ui->logarithm->checkState() == Qt::Checked){ // 选中对数图
            this->logarithmCurve();
        }else { // 普通曲线
            this->renderResultCurve();
        }
    });


    /* 曲线归一化 */
    connect(ui->guiYiHua, &QCheckBox::toggled, this, [=](bool status){
        if(status){ // 开启归一化
            // 信号阻塞
            ui->showYuZhiXian->blockSignals(true);
            ui->logarithm->blockSignals(true);
            ui->showYuZhiXian->setChecked(!status); // 不显示阈值线
            ui->logarithm->setChecked(!status); // 对数曲线取消
            // 信号阻塞解除
            ui->showYuZhiXian->blockSignals(false);
            ui->logarithm->blockSignals(false);

            isGuiYi = 1; // 开启归一化

            resultYAxisMax = this->resultYAxis->max(); // 记录y轴最大值
            resultYAxisMin = this->resultYAxis->min(); // 记录y轴最小值

            resultYAxis->setTickType(QValueAxis::TickType::TicksFixed); // 改变刻度格式：固定型
            resultYAxis->setRange(0, 1); // 设置y轴范围为0-1
            resultYAxis->setLabelFormat("%.2f"); // 设置y轴的标签格式：浮点数型
        }else {
            isGuiYi = 0; // 关闭归一化
        }
        ui->logarithm->setEnabled(!status); // 对数曲线按钮设置
        ui->showYuZhiXian->setEnabled(!status); // 阈值线按钮设置
        this->renderResultCurve(); // 渲染结果曲线
    });

    /* 曲线计算deltaRn */
    connect(ui->yuanShiRn, &QCheckBox::toggled, this, [=](bool status){
        if(status){ // 关闭原始Rn计算
            this->isDeltaRn = 0;
        }else { // 开启原始Rn计算
            this->isDeltaRn = 1;
        }
        yuZhiHash = initYuZhi(yuZhiHash); // 阈值Hash初始化
        if(ui->logarithm->checkState() == Qt::Unchecked){
            this->renderResultCurve(); // 渲染结果曲线
        }else {
            this->logarithmCurve(); // 渲染对数图
        }
    });

    /* Rn时禁用归一化 */
     connect(ui->yuanShiRn, &QCheckBox::toggled, ui->guiYiHua, &QWidget::setDisabled);

}

void ExperimentResultUi::receiveKey(QString key) {

    LOG << "zzzzz" << yuZhiLabelHash;
    if (key == "fam" || key == "vic" || key == "rox" || key == "cy5")
    {
        this->resultChart->yuZhiLabelHash[key]->setReadOnly(false); // 将指定yuzhilineedit改为可编辑
        this->resultChart->yuZhiLabelHash[key]->setFocus(); // 将焦点转移至yuzhilineedit上
    }

}


ExperimentResultUi::~ExperimentResultUi()
{
    delete ui;
}

/* 更改yuzhihash */
void ExperimentResultUi::updateSingalYuzhi(QString key,double text){
    if(this->yuZhiHash.keys().contains(key)) { // 如果这个key在阈值Hash的key中
        this->resultChart->yuZhiHash[key] = text;  // 更改阈值线的y

        LOG << this->yuZhiHash;

        LOG << this->yuZhiHash << "resultchart" << this->resultChart->yuZhiHash;
        QHash<QString, double> tYuZhiHash = this->yuZhiHash;
    }
}

/* 下一步 */
void ExperimentResultUi::nextCallback(){
    /* 发送下一步信号 */
    emit ExperimentResultUi::nextEvent();
}

/* 返回数据信息 */
QList<QString> ExperimentResultUi::returnPageInfos(){
    /* ct */
    QList<QString> ctList, reverseCtList; // 转换的ctlist
    int ctSize = this->ct.size();
    int columnCount = 4;
    // 将原始ct转换为String类型后再添加到新列表中
    for(int i = 0; i < ctSize; i++){
        ctList.append(QString::number(this->ct[i]));
    }
    // 按列取出ct值，根据反应板所选靶基因情况，重新写入新的ct值
    if(ctSize != 0){
        // 将按列存储的ct值改为按行存储返回
        for(int i = 0; i < 8; i++){
            for(int j = 0; j < columnCount; j++){
                for(int k = 0; k < 4; k++){
                    reverseCtList.append(ctList[(i+8*j)*4+k]);
                }
            }
        }
    }

    return reverseCtList;
}

/* 发送荧光曲线数据 */
QList<QList<QHash<QString, QString>>> ExperimentResultUi::sendYingguangData(){
    return this->saveYingguangDataList;
}

/* 获取结果页所需数据 */
void ExperimentResultUi::getResultData(){
    /* 清除横轴数据 */
    int preXAxisMax = this->resultXAxis->count();

    for(int i = 0; i < preXAxisMax; i++){
        this->resultXAxis->remove(QString::number(i+1));
    }

    /* 渲染横轴大小和刻度 */
    this->resultXAxis->setRange(0, this->cyclingNum-1);
    this->resultXAxis->setTickCount(this->cyclingNum);

    /* 设置横轴数据 */
    for(int i = 0; i < this->cyclingNum; i++){
        this->resultXAxis->append(QString::number(i+1), i);
        resultChart->update();
    }

    /* 同步反应板 */
    this->targetLegend = this->getReactionPlateTarget();

    /* 渲染反应板 */
    this->renderResultTable();
    /* 渲染曲线过滤列表 */
    this->renderFilterList();

    /* 根据反应板靶基因，初始化数据分析所用的靶基因信息 */
    this->targetNameList.clear(); // 清空靶基因名字列表
    this->alysTar.clear(); // 数据分析靶基因清除
    int reactionPlateRows = 96;
    QList<QHash<QString, QString>> tarNameList; // 靶基因名字列表
    for(int i = 0; i < reactionPlateRows; i++){
        int tarCnt = sizeof(this->reactionPlate.targetList[i])/sizeof(Target); // 靶基因个数
        for(int j = 0; j < tarCnt; j++){
            if(this->reactionPlate.targetList[i][j].name != "null"){
                QHash<QString, QString> reporterMapToName; // 报告基因映射名称
                QString tarName = this->reactionPlate.targetList[i][j].name;
                QString reporter = this->reactionPlate.targetList[i][j].reporter;
                reporterMapToName.insert(reporter.toLower(), tarName);
                tarNameList.append(reporterMapToName);
            }
        }
    }

    this->targetNameList = tarNameList.toSet().toList(); // 名称去重

    if(this->alyscfg != nullptr){     // TODO
        /* 工具栏：分析配置应用，重新运行数据分析信息 */
        connect(alyscfg, &AnalysisConfig::updateAnalysisConfig, this, [=](){
            LOG << "ok了";                 // TODO
            if(ui->logarithm->checkState() == Qt::Checked){ // 选中对数图
                this->logarithmCurve();
            }else { // 普通曲线
                this->renderResultCurve();
            }
        });
    }
}

/* 配置分析工具栏更新，重新渲染数据分析相关信息 */
void ExperimentResultUi::updateDataAnalysisInfo(QList<AnalysisTarget> alysTar){
    // 写入数据分析所用的靶基因
    this->alysTar = alysTar;
    // 拆分靶基因数据到各个变量
    this->splitTargetToValues(this->alysTar);
    this->updateCurveData = true; // 重新更新曲线
    // 渲染曲线
    if(ui->logarithm->checkState() == Qt::Checked){ // 选中对数图
        this->logarithmCurve();
    }else { // 普通曲线
        this->renderResultCurve();
    }
}

/* 创建结果页面图表 */
void ExperimentResultUi::createResultChart(){
    /* 绘制坐标轴 */
    resultChart = new ResultCurveChart();
    resultChart->setTheme(QChart::ChartThemeQt);
    resultChart->setMargins(QMargins(0, 0, 0, 0));
    // 抗锯齿
    ui->resultGraphicsView->setRenderHint(QPainter::Antialiasing);
    // 添加坐标轴
    resultXAxis = new QCategoryAxis();
    resultYAxis = new QValueAxis();
    logarithmYAxis = new QCategoryAxis(); // 对数图坐标轴
    // 默认隐藏对数图坐标轴
    logarithmYAxis->hide();
    // 坐轴范围
    resultXAxis->setStartValue(0);
    resultXAxis->setRange(0, 0);
    resultYAxis->setRange(0, 8000);
    logarithmYAxis->setStartValue(0);
    logarithmYAxis->setRange(0, logarithmYMaxiMum);
    // 轴标签设置
    resultXAxis->setLabelFormat("%d");
    resultYAxis->setLabelFormat("%d");
    // y轴刻度默认设置 8 个
    resultYAxis->setTickType(QValueAxis::TickType::TicksDynamic); // 动态设置y轴数据
    resultYAxis->setTickAnchor(0); // 设置锚点为 0
    resultYAxis->setTickInterval(1000); // 设置间隔为 1000（不算原点，八个单元格）
    // 设置对数图y轴数据
    logarithmYAxis->append("10³", 100);
    logarithmYAxis->append("10⁴", 1000);
    logarithmYAxis->append("10⁵", logarithmYMaxiMum);
//    logarithmYAxis->append("A", 1000000);
    // 图例不可见
    resultChart->legend()->setVisible(false);
    // 图表名称
    resultChart->setTitle("扩增图谱");
    // 坐标轴名称
    resultXAxis->setTitleText("循环数");
    resultYAxis->setTitleText("ΔRn");
    logarithmYAxis->setTitleText("Rn(log)");
    // 设置图表刻度
    logarithmYAxis->setTickCount(logarithmYAxis->count());
    // 让刻度线和刻度的label对齐
    resultXAxis->setLabelsPosition(QCategoryAxis::AxisLabelsPositionOnValue);
    logarithmYAxis->setLabelsPosition(QCategoryAxis::AxisLabelsPositionOnValue);
    // 创建并绑定阈值序列
    this->yuZhiSeries = this->createAndSetYuZhiSeries(this->validYuZhiList);

    // 绑定数据系列
    for(int i = 0; i < 96; i++){
        QSplineSeries *cy5Series = new QSplineSeries();
        QSplineSeries *famSeries = new QSplineSeries();
        QSplineSeries *vicSeries = new QSplineSeries();
        QSplineSeries *roxSeries = new QSplineSeries();
        // 添加数据序列
        resCy5SeriesList.append(cy5Series);
        resFamSeriesList.append(famSeries);
        resVicSeriesList.append(vicSeries);
        resRoxSeriesList.append(roxSeries);
    }

    // 向图表中加入横纵轴
    resultChart->addAxis(resultXAxis, Qt::AlignBottom); // x轴
    resultChart->addAxis(resultYAxis, Qt::AlignLeft); // y轴
    resultChart->addAxis(logarithmYAxis, Qt::AlignLeft); // 对数图y轴

    // 图标添加序列
    for(int i = 0; i < 96; i++){
        resultChart->addSeries(resFamSeriesList[i]);
        resultChart->addSeries(resVicSeriesList[i]);
        resultChart->addSeries(resRoxSeriesList[i]);
        resultChart->addSeries(resCy5SeriesList[i]);
    }

    // 序列绑定坐标轴
    for(int i = 0; i < 96; i++){
        // fam
        resFamSeriesList[i]->attachAxis(resultXAxis);
        resFamSeriesList[i]->attachAxis(resultYAxis);
        resFamSeriesList[i]->attachAxis(logarithmYAxis);
        // vic
        resVicSeriesList[i]->attachAxis(resultXAxis);
        resVicSeriesList[i]->attachAxis(resultYAxis);
        resVicSeriesList[i]->attachAxis(logarithmYAxis);
        // rox
        resRoxSeriesList[i]->attachAxis(resultXAxis);
        resRoxSeriesList[i]->attachAxis(resultYAxis);
        resRoxSeriesList[i]->attachAxis(logarithmYAxis);
        // cy5
        resCy5SeriesList[i]->attachAxis(resultXAxis);
        resCy5SeriesList[i]->attachAxis(resultYAxis);
        resCy5SeriesList[i]->attachAxis(logarithmYAxis);
    }

    /* 在 ChartsView 上渲染 ResultCurveCharts */
    ui->resultGraphicsView->setChart(resultChart);

    /* 初始化图表信息 */
    resultChart->init(yuZhiSeries, ui->resultGraphicsView);

    //修改坐标轴字体
    QFont chartFont, xAxisFont, yAxisFont;
    const int chartFontSize = 9, xAxisFontSize = 6; // y轴标签字体大小是chartFontSize
    chartFont.setFamily("Alibaba PuHuiTi");
    chartFont.setPointSize(chartFontSize);
    chartFont.setBold(true);
    xAxisFont.setFamily("Alibaba PuHuiTi");
    xAxisFont.setPointSize(xAxisFontSize);
    yAxisFont.setFamily("Alibaba PuHuiTi");
    yAxisFont.setPointSize(chartFontSize);
    resultXAxis->setLabelsFont(xAxisFont); // x
    resultXAxis->setTitleFont(chartFont);
    resultYAxis->setLabelsFont(yAxisFont); // y
    resultYAxis->setTitleFont(chartFont);
    logarithmYAxis->setLabelsFont(yAxisFont); // log
//    logarithmYAxis->setTitleFont(chartFont);
    resultChart->setTitleFont(chartFont); // chart

    /* 鼠标释放，监听事件，更新当前页面阈值 */
    connect(resultChart, &ResultCurveChart::updateYuZhi, this, &ExperimentResultUi::renderYuzhiSlot);
    /* 左键双击，监听事件，编辑yuzhilineedit */
    connect(this->resultChart, &ResultCurveChart::returnYuzhiHash, this, &ExperimentResultUi::receiveKey);


    /* 显示/隐藏阈值线按钮 */
    connect(ui->showYuZhiXian, &QCheckBox::toggled, this, [=](bool checked){
        if(checked){ // 显示阈值线
            this->yuZhiLineFilter(); // 考虑单通道过滤情况
            /* 绑定所有图表鼠标事件 */
            resultChart->connectPressEvent();
            resultChart->connectMoveEvent();
            resultChart->connectReleaseEvent();
            resultChart->connectDoubleClickEvent();
            resultChart->connectChangeEvent();
        }else { // 隐藏阈值线
            /* 解绑所有图表鼠标事件 */
            resultChart->disconnectPressEvent();
            resultChart->disconnectMoveEvent();
            resultChart->disconnectReleaseEvent();
            resultChart->disconnectDoubleClickEvent();
            resultChart->disconnectChangeEvent();
            this->validYuZhiList.clear(); // 清空合法阈值
            resultChart->clear(); // 清空图表
        }
        resultChart->update(); // 图标刷新
        this->resultChart->update(); // 图标引擎刷新
        if(ui->logarithm->checkState() == Qt::Unchecked){
            this->renderResultCurve();
        }else {
            this->logarithmCurve();
        }
    });

    /* todo 监测曲线和阈值线，动态调整y轴最大值 */
    for(QSplineSeries *famSeries : qAsConst(resFamSeriesList)){
        connect(famSeries, &QSplineSeries::pointAdded, this, [=](int index){
            if(this->yAxisMaximum < static_cast<int>(famSeries->points().at(index).y())){
                this->yAxisMaximum = static_cast<int>(famSeries->points().at(index).y());
                resultChart->updateMapUnit(); // 更新单元长度
            }
        });
    }
    for(QSplineSeries *vicSeries : qAsConst(resVicSeriesList)){
        connect(vicSeries, &QSplineSeries::pointAdded, this, [=](int index){
            if(this->yAxisMaximum < static_cast<int>(vicSeries->points().at(index).y())){
                this->yAxisMaximum = static_cast<int>(vicSeries->points().at(index).y());
                resultChart->updateMapUnit(); // 更新单元长度
            }
        });
    }
    for(QSplineSeries *roxSeries : qAsConst(resRoxSeriesList)){
        connect(roxSeries, &QSplineSeries::pointAdded, this, [=](int index){
            if(this->yAxisMaximum < static_cast<int>(roxSeries->points().at(index).y())){
                this->yAxisMaximum = static_cast<int>(roxSeries->points().at(index).y());
                resultChart->updateMapUnit(); // 更新单元长度
            }
        });
    }
    for(QSplineSeries *cy5Series : qAsConst(resCy5SeriesList)){
        connect(cy5Series, &QSplineSeries::pointAdded, this, [=](int index){
            if(this->yAxisMaximum < static_cast<int>(cy5Series->points().at(index).y())){
                this->yAxisMaximum = static_cast<int>(cy5Series->points().at(index).y());
                resultChart->updateMapUnit(); // 更新单元长度
            }
        });
    }

    const QStringList yuZhiSeriesKeys = this->yuZhiSeries.keys();
    for(const QString &key : yuZhiSeriesKeys){
        connect(this->yuZhiSeries[key], &QSplineSeries::pointAdded, this, [=](int index){
            if(this->yAxisMaximum < static_cast<int>(this->yuZhiSeries[key]->points()[index].y())){
                this->yAxisMaximum = static_cast<int>(this->yuZhiSeries[key]->points()[index].y());
                resultChart->updateMapUnit(); // 更新单元长度
            }
        });
    }

}

/* 返回数据分析用靶基因 */
QList<AnalysisTarget> ExperimentResultUi::getAnalysisTarget(){
    LOG << "返回靶基因";

    for(int i = 0; i < this->alysTar.size(); i++){
        LOG << this->alysTar[i].id << this->alysTar[i].targetName << this->alysTar[i].jiXianStart << this->alysTar[i].jiXianEnd;
    }

    LOG << "结束靶基因";

    return this->alysTar;
}

/* 数据分析函数 */
void ExperimentResultUi::dataAnalysis(){
    /* 不重要变量 */
    QList<double> ctaaa;
    QList<QHash<QString, QString>> yuzhibbb;
    QList<QList<QHash<QString, QString>>> ygygccc;
    QList<QString> tttValidYuZhiList; // 合法阈值线数组
    /* 不重要变量 */

    QList<QHash<QString, QString>> allYuZhi; // 未解析阈值

    resultChart->clear(); // 清空图表数据
    this->renderYingGuang.clear(); // 清空结果要渲染的曲线

    /* 获取配置文件中的分析配置 */
    std::tie(this->alysConfigs, this->alysCfgYuZhi) = alyscfg->getAnalysisConfig();

    /* 获取数据分析信息 */
    // 初始化：先不渲染曲线，获取初始化阈值
    if(this->yuZhiHash["fam"] == 0.0 ||
            this->yuZhiHash["vic"] == 0.0 ||
            this->yuZhiHash["rox"] == 0.0 ||
            this->yuZhiHash["cy5"] == 0.0){
        std::tie(ygygccc, ctaaa, allYuZhi) = dAlys->PROCDataAnalyse(
                    this->saveYingguangDataList,
                    alysConfigs["shuaiJianSwitch"],
                alysConfigs["ctMethod"],
                this->baseLineList,
                this->yuZhiHash["fam"],
                this->yuZhiHash["vic"],
                this->yuZhiHash["rox"],
                this->yuZhiHash["cy5"],
                alysConfigs["shuaiJianMethod"],
                alysConfigs["lvBoMethod"],
                isGuiYi,
                isDeltaRn);
        LOG << "yuyu" <<allYuZhi;

        this->yuZhiHash = this->yuZhiCalculation(allYuZhi); // 计算阈值
    }

    // 获取阈值后，再渲染曲线
    std::tie(ygygccc, this->ct, allYuZhi) = dAlys->PROCDataAnalyse(
                this->saveYingguangDataList,
                alysConfigs["shuaiJianSwitch"],
            alysConfigs["ctMethod"],
            this->baseLineList,
            this->yuZhiHash["fam"],
            this->yuZhiHash["vic"],
            this->yuZhiHash["rox"],
            this->yuZhiHash["cy5"],
            alysConfigs["shuaiJianMethod"],
            alysConfigs["lvBoMethod"],
            isGuiYi,
            isDeltaRn);

    /* 获取曲线数据 */
    if(updateCurveData){
        // 并计算拟合曲线数据，写入变量
        std::tie(this->analysingYingGuang, ctaaa, yuzhibbb) = dAlys->PROCDataAnalyse(
                    this->saveYingguangDataList,
                    alysConfigs["shuaiJianSwitch"],
                alysConfigs["ctMethod"],
                this->baseLineList,
                this->yuZhiHash["fam"],
                this->yuZhiHash["vic"],
                this->yuZhiHash["rox"],
                this->yuZhiHash["cy5"],
                alysConfigs["shuaiJianMethod"],
                alysConfigs["lvBoMethod"],
                0,
                0);

        // 并计算delta曲线数据，写入变量
        std::tie(this->deltaYingGuang, ctaaa, yuzhibbb) = dAlys->PROCDataAnalyse(
                    this->saveYingguangDataList,
                    alysConfigs["shuaiJianSwitch"],
                alysConfigs["ctMethod"],
                this->baseLineList,
                this->yuZhiHash["fam"],
                this->yuZhiHash["vic"],
                this->yuZhiHash["rox"],
                this->yuZhiHash["cy5"],
                alysConfigs["shuaiJianMethod"],
                alysConfigs["lvBoMethod"],
                0,
                1);

        // 计算归一化荧光值
        // 拟合归一化荧光
        std::tie(this->alysGuiYiYingGuang, ctaaa, yuzhibbb) = dAlys->PROCDataAnalyse(
                    this->saveYingguangDataList,
                    alysConfigs["shuaiJianSwitch"],
                alysConfigs["ctMethod"],
                this->baseLineList,
                this->yuZhiHash["fam"],
                this->yuZhiHash["vic"],
                this->yuZhiHash["rox"],
                this->yuZhiHash["cy5"],
                alysConfigs["shuaiJianMethod"],
                alysConfigs["lvBoMethod"],
                1,
                0);
        // delta归一化荧光
        std::tie(this->deltaGuiYiYingGuang, ctaaa, yuzhibbb) = dAlys->PROCDataAnalyse(
                    this->saveYingguangDataList,
                    alysConfigs["shuaiJianSwitch"],
                alysConfigs["ctMethod"],
                this->baseLineList,
                this->yuZhiHash["fam"],
                this->yuZhiHash["vic"],
                this->yuZhiHash["rox"],
                this->yuZhiHash["cy5"],
                alysConfigs["shuaiJianMethod"],
                alysConfigs["lvBoMethod"],
                1,
                1);
        this->updateCurveData = false; // 更新曲线数据关闭
    }
    /* 赋值渲染变量 */
    if(isGuiYi == 1){ // 是归一化
        if(isDeltaRn == 1){ // 是delta
            this->renderYingGuang = this->deltaGuiYiYingGuang;
        }else { // 是拟合
            this->renderYingGuang = this->alysGuiYiYingGuang;
        }
    }else { // 不是归一化
        if(isDeltaRn == 1){ // 是delta
            this->renderYingGuang = this->deltaYingGuang;
            LOG << "非归一selta";
        }else { // 是拟合
            LOG << "非归一拟合";
            this->renderYingGuang = this->analysingYingGuang;
        }
    }

    // 计算阈值
    std::tie(this->colorHash, tttValidYuZhiList) = this->getTargetColor(); // 获取靶基因颜色并写入合法阈值
    if(ui->colorMarked->currentText().contains("靶基因")){ // 根据靶基因颜色获取阈值颜色
        // 目前不处理
    }else if(ui->colorMarked->currentText().contains("样本")){ // 根据样本颜色获取阈值颜色
        this->colorHash = this->getSampleColor();
    }

    this->yuZhiHash = this->yuZhiCalculation(allYuZhi); // 计算阈值
    //    LOG << "RESSULTyuZHiHash" << this->yuZhiHash;

    /* 阈值 */
    if(ui->showYuZhiXian->checkState() == Qt::Checked){ // 如果阈值线渲染勾选
        this->renderYuZhiData(); // 渲染阈值相关数据
    }

    //    过滤所有的ct值，当阈值线显示并且当前靶基因阈值线大于或小于当前靶基因时，ct值赋值nan。
    //    将阈值线的值与曲线最大最小值比较
    this->ctFilter(); // 过滤阈值线超过曲线的ct值

//    /* ct值 */ // 将此方法调用移动到上面的ctFilter()
//    this->renderRplateCts(this->ct, QList<bool>()); // 渲染反应板ct值

    /* 写入数据分析所用的靶基因 */
    if(this->alysTar.size() == 0){ // 第一次执行
        this->alysTar = this->setAnalysisTargetData(this->targetNameList, this->yuZhiHash, this->baseLineList);
        this->firstInitAlysTar = false;
    }else {
        this->updateAnalysisTargetData(this->targetNameList, this->yuZhiHash, this->baseLineList);
    }

    /* 自动导出 */
    if(this->autoExportFlag && (preferencesService->getPreferencesData())["auto-export"] == "1"){
        this->autoExportFlag = false; // 只自动导出一次
        emit ExperimentResultUi::sigExport(); // 发送导出信号
    }
}

/* 创建并绑定阈值序列 */
QHash<QString, QSplineSeries*> ExperimentResultUi::createAndSetYuZhiSeries(QList<QString> validYuZhiList){
    QHash<QString, QSplineSeries*> res; // 合法阈值系列

    QList<QString> validList;
    validList.append("fam");       // TODO
    validList.append("vic");
    validList.append("rox");
    validList.append("cy5");

//    validYuZhiList.append("fam");
//    validYuZhiList.append("vic");
//    validYuZhiList.append("rox");
//    validYuZhiList.append("cy5");
    // 根据合法阈值列表，创建并添加阈值系列（目前写死4个）
    for(const QString yuZhi : validList){
        res.insert(yuZhi, new QSplineSeries);
        resultChart->addSeries(res[yuZhi]);
        /* 绑定坐标轴 */
        resultChart->setAxisX(resultXAxis, res[yuZhi]);
        resultChart->setAxisY(resultYAxis, res[yuZhi]);
    }
    return res;
}

/* 初始化阈值Hash */
QHash<QString, double> ExperimentResultUi::initYuZhi(QHash<QString, double> yuZhiHash){
    yuZhiHash.insert("fam", 0);
    yuZhiHash.insert("vic", 0);
    yuZhiHash.insert("rox", 0);
    yuZhiHash.insert("cy5", 0);
    return yuZhiHash;
}

/* 阈值计算函数 */
QHash<QString, double> ExperimentResultUi::yuZhiCalculation(QList<QHash<QString, QString>> allYuZhi){
    double famYuZhi = 0, vicYuZhi = 0, roxYuZhi = 0, cy5YuZhi = 0;
    QHash<QString, double> res;
    int yuZhiListSize = allYuZhi.size();
    LOG << "uuuuu**********&^T^Y^T&%%%%%%%%%%%%%%%(?^TT%RRRRRRRRRR" <<allYuZhi;
    /* 遍历阈值 */
    for(int i = 0; i < yuZhiListSize; i++){
        QHash<QString, QString> yuZhi = allYuZhi[i];
        if(yuZhi["1"] != "nan"){
            if(yuZhi["1"].toDouble() > famYuZhi){
                famYuZhi = yuZhi["1"].toDouble();
            }
        }
        if(yuZhi["2"] != "nan"){
            if(yuZhi["2"].toDouble() > vicYuZhi){
                vicYuZhi = yuZhi["2"].toDouble();
            }
        }
        if(yuZhi["3"] != "nan"){
            if(yuZhi["3"].toDouble() > roxYuZhi){
                roxYuZhi = yuZhi["3"].toDouble();
            }
        }
        if(yuZhi["4"] != "nan"){
            if(yuZhi["4"].toDouble() > cy5YuZhi){
                cy5YuZhi = yuZhi["4"].toDouble();
            }
        }
    }
    res.insert("fam", famYuZhi);
    res.insert("vic", vicYuZhi);
    res.insert("rox", roxYuZhi);
    res.insert("cy5", cy5YuZhi);

    return res;
}

/* 阈值渲染 */
void ExperimentResultUi::renderYuZhiLine(QHash<QString, double> yuZhiHash, QHash<QString, QColor> yuZhiLineColor){
    /* 设置阈值线颜色 */
    QList<QString> yuZhiKeys = yuZhiSeries.keys();
    for(QString key : yuZhiKeys){
        if(yuZhiLineColor[key].isValid()){ // 如果颜色合法，则渲染
            yuZhiSeries[key]->setPen(QPen(yuZhiLineColor[key])); // 渲染颜色
        }
    }
    /* 渲染阈值线 */
    for(QString key : yuZhiKeys){
//        yuZhiSeries[key]->clear();   // TODO
        for(int i = 0; i < this->cyclingNum; i++){
            if(validYuZhiList.contains(key)){ // 合法阈值
                yuZhiSeries[key]->append(i, yuZhiHash[key]); // 阈值线加入数据
            }else {
                break; // 阈值不合法，进入下一轮循环
            }
        }
    }
}

/* 获取靶基因颜色列表 */
std::tuple<QHash<QString, QColor>, QList<QString>> ExperimentResultUi::getTargetColor(){
    QHash<QString, QColor> resColor; // 结果颜色列表
    QList<QString> validYuZhi; // 合法阈值列表
    QString famString = "", vicString = "", roxString = "", cy5String = ""; // 名称初始化
    // 颜色初始化
    int famColorR = -1, famColorG = -1, famColorB = -1,
            vicColorR = -1, vicColorG = -1, vicColorB = -1,
            roxColorR = -1, roxColorG = -1, roxColorB = -1,
            cy5ColorR = -1, cy5ColorG = -1, cy5ColorB = -1;
    int plateKongWei = 96; // 孔位初始化

    /* 遍历反应板，获取每个靶基因颜色 */
    for(int i = 0; i < plateKongWei; i++){
        for(int j = 0; j < 4; j++){
            if(this->reactionPlate.targetList[i][j].color != "null"){
                // fam
                if(this->reactionPlate.targetList[i][j].reporter.toLower() == "fam"
                        && famColorR == -1){
                    QList<QString> famColorList = this->reactionPlate.targetList[i][j].color.split(",");
                    if(famColorList.size() == 3){
                        famColorR = famColorList[0].toInt();
                        famColorG = famColorList[1].toInt();
                        famColorB = famColorList[2].toInt();
                        famString = this->reactionPlate.targetList[i][j].reporter; // 存入当前靶基因报告基因名称
                    }
                }
                // vic
                if(this->reactionPlate.targetList[i][j].reporter.toLower() == "vic"
                        && vicColorR == -1){
                    QList<QString> vicColorList = this->reactionPlate.targetList[i][j].color.split(",");
                    if(vicColorList.size() == 3){
                        vicColorR = vicColorList[0].toInt();
                        vicColorG = vicColorList[1].toInt();
                        vicColorB = vicColorList[2].toInt();
                        vicString = this->reactionPlate.targetList[i][j].reporter; // 存入当前靶基因报告基因名称
                    }
                }
                // rox
                if(this->reactionPlate.targetList[i][j].reporter.toLower() == "rox"
                        && roxColorR == -1){
                    QList<QString> roxColorList = this->reactionPlate.targetList[i][j].color.split(",");
                    if(roxColorList.size() == 3){
                        roxColorR = roxColorList[0].toInt();
                        roxColorG = roxColorList[1].toInt();
                        roxColorB = roxColorList[2].toInt();
                        roxString = this->reactionPlate.targetList[i][j].reporter; // 存入当前靶基因报告基因名称
                    }
                }
                // cy5
                if(this->reactionPlate.targetList[i][j].reporter.toLower() == "cy5"
                        && cy5ColorR == -1){
                    QList<QString> cy5ColorList = this->reactionPlate.targetList[i][j].color.split(",");
                    if(cy5ColorList.size() == 3){
                        cy5ColorR = cy5ColorList[0].toInt();
                        cy5ColorG = cy5ColorList[1].toInt();
                        cy5ColorB = cy5ColorList[2].toInt();
                        cy5String = this->reactionPlate.targetList[i][j].reporter; // 存入当前靶基因报告基因名称
                    }
                }
            }

            if(famColorR != -1 && famColorG != -1 && famColorB != -1 &&
                    vicColorR != -1 && vicColorG != -1 && vicColorB != -1 &&
                    roxColorR != -1 && roxColorG != -1 && roxColorB != -1 &&
                    cy5ColorR != -1 && cy5ColorG != -1 && cy5ColorB != -1){ // 所有颜色都已经存在，退出循环
                break;
            }
        }
    }
    /* 存入颜色 */
    if(famColorR != -1){
        resColor.insert(famString.toLower(), QColor(famColorR, famColorG, famColorB, 255));
    }
    if(vicColorR != -1){
        resColor.insert(vicString.toLower(), QColor(vicColorR, vicColorG, vicColorB, 255));
    }
    if(roxColorR != -1){
        resColor.insert(roxString.toLower(), QColor(roxColorR, roxColorG, roxColorB, 255));
    }
    if(cy5ColorR != -1){
        resColor.insert(cy5String.toLower(), QColor(cy5ColorR, cy5ColorG, cy5ColorB, 255));
    }

    /* 根据颜色，判断不合法阈值 */
    if(validYuZhi.size() != 0){
        validYuZhi.clear(); // 初始化合法阈值线数组
    }
    for(QString key : resColor.keys()){
        if(resColor[key].isValid()){ // 颜色合法，加入合法阈值列表
            validYuZhi.append(key);
        }
    }

    std::tuple<QHash<QString, QColor>, QList<QString>> res = {resColor, validYuZhi}; // 结果元组

    return res;
}

/* 获取样本颜色列表 */
QHash<QString, QColor> ExperimentResultUi::getSampleColor(){
    QHash<QString, QColor> resColor; // 结果颜色列表
    // 颜色初始化
    int colorR = -1, colorG = -1, colorB = -1;
    int plateKongWei = 96; // 孔位初始化

    /* 遍历反应板，获取每个靶基因颜色 */
    for(int i = 0; i < plateKongWei; i++){
        if(this->reactionPlate.sampleList[i].color_value != "null"){
            QList<QString> colorList = this->reactionPlate.sampleList[i].color_value.split(",");
            if(colorList.size() == 3){
                colorR = colorList[0].toInt();
                colorG = colorList[1].toInt();
                colorB = colorList[2].toInt();
            }
        }
        if(colorR != -1 && colorG != -1 && colorB != -1){ // 所有颜色都已经存在，退出循环
            break;
        }
    }

    /* 根据合法阈值存入颜色 */
    if(colorR != -1){
        for(QString yuZhiName : this->validYuZhiList){
            resColor.insert(yuZhiName, QColor(colorR, colorG, colorB, 255));
        }
    }else {
        for(QString yuZhiName : this->validYuZhiList){
            resColor.insert(yuZhiName, QColor(0, 0, 0, 0));
        }
    }

    QHash<QString, QColor> res = resColor; // 结果元组

    return res;
}

/* 生成阈值label */
QHash<QString, YuzhiLineEdit*> ExperimentResultUi::yuZhiLabel(QHash<QString, QColor> labelTextColor){
    QHash<QString, YuzhiLineEdit*> res; // 结果
    /* 根据合法阈值数组，新建阈值标签 */
    int validYuZhiListCnt = this->validYuZhiList.size();



    for(int i = 0; i < validYuZhiListCnt; i++){
        YuzhiLineEdit *tYuzhiLineEdit  = new YuzhiLineEdit(ui->resultGraphicsView);

        tYuzhiLineEdit->yuzhiID = this->validYuZhiList[i];
        tYuzhiLineEdit->getResultrchart(this);

        connect(tYuzhiLineEdit, &YuzhiLineEdit::returnYuzhi, this, &ExperimentResultUi::updateSingalYuzhi);
//        connect(tYuzhiLineEdit, &YuzhiLineEdit::returnYuzhi, this->resultChart, &ResultCurveChart::finishEditEvent);
        res.insert(this->validYuZhiList[i], tYuzhiLineEdit);
    }

    /* 当选中所有通道时yuzhilineedit不可用 */
    if(this->validYuZhiList.size() == this->yuZhiSeries.size()){
        for(QString key:validYuZhiList){
            res[key]->setEnabled(false);
        }
    }
    else{
        for(QString key:validYuZhiList){
            res[key]->setEnabled(true);
        }
    }
    /* 设置标签基本文字和样式 */
    QList<QString> labelKeys = res.keys();
    for(QString key : labelKeys){
        /* 设置颜色 */
        QColor color(labelTextColor[key]);
        QString colorStyleSheet = "color: rgba(" +
                QString::number(color.red()) + "," +
                QString::number(color.green()) + "," +
                QString::number(color.blue()) + "," +
                QString::number(color.alpha()) +
                ");";
        res[key]->setStyleSheet("QLineEdit{"
                                "min-width: 50px;"
                                "font-size: 16px;"
                                "border: none;"
                                "background-color: transparent;"
                                "font-family: 'Alibaba PuHuiTi';" +
                                colorStyleSheet +
                                "}");
        res[key]->adjustSize(); // 标签自适应大小
        res[key]->show(); // 标签显示
    }

    /* 设置阈值标签文字 */
    for(QString key : labelKeys){
        res[key]->setText(QString::number(this->yuZhiHash[key], 'f', 2));
    }


    return res;
}


/* 渲染阈值相关数据 */
void ExperimentResultUi::renderYuZhiData(){
    // 阈值渲染
    renderYuZhiLine(this->yuZhiHash, this->colorHash); // 阈值线渲染
    this->yuZhiLabelHash = yuZhiLabel(this->colorHash); // 生成阈值标签


    this->resultChart->setSeriesInfo(this->yuZhiHash, this->colorHash,
                                     this->yuZhiLabelHash, this->validYuZhiList); // 输入阈值渲染所用信息
}

/* 渲染结果页面反应板列表ct值 */
void ExperimentResultUi::renderRplateCts(QList<double> ct, QList<bool> yuZhiLineFilterCt) {
    QTableWidget *rpListTable = ui->resultDetailTable; // 获取列表反应板
    int row = rpListTable->rowCount(); // 获取行数
    int currentRow = 0; // 当前所在行
    QTableWidgetItem *idItem; // 第0行id列item


    /* 根据第六列的id，按顺序渲染添加ct值（id从0开始） */
    while(currentRow != row){
//       此while循环内部LOG用来debug用 LOG << "----------line " << currentRow;
        idItem = rpListTable->item(currentRow, 6); // 查看新的id行
        // 如果id单元格有数据
        if(idItem && idItem->text() != ""){
            int id = idItem->text().toInt(); // 数据id
            int idCellMap2Row = idItem->row(); // 返回id单元格所在行
            QString ctText = QString::number(ct[id], 'f', 2);
            if (ctText.contains("e") ||!QString::compare(ctText, "0.00") || !yuZhiLineFilterCt[currentRow]) { // 1.97626e-322 判断为nan
                ctText = "nan";
//                LOG << "含有e or 0.00相等 or 阈值线超过曲线";
            }
            rpListTable->setItem(idCellMap2Row, 5, new QTableWidgetItem(ctText)); // 写入ct值
//            LOG << "ct值" << ctText;
        }
        currentRow++; // 当前行自增
    }
}

// todo 这个函数被调用两次，考虑父方法被调用两次
void ExperimentResultUi::ctFilter() {
    //    this-ct; // 每个靶基因的ct值
    //    this->yuZhiHash; // 四条阈值线的值
//    LOG << yuZhiHash["fam"] << yuZhiHash["cy5"] << yuZhiHash["rox"] << yuZhiHash["vic"];
//    LOG << ct.length();
//    for (int ctKey = 0; ctKey < ct.length(); ctKey ++ ) {
//        LOG << ctKey << "ct值    ----- " << ct[ctKey];
//    }
//    LOG << cyclingNum; // 循环次数 横轴最大值
    // 存储每条曲线的最大deltaRn值和最小deltaRn值
    //    32孔位   每孔位4靶基因 每靶基因2个Hash存储最大最小值 "max" "min"
    QString DOUBLE_MAX = "1e30";
    QString DOUBLE_MIN = "-1";
    // todo 写一个遍历qList方法， 让yuZhiHash跟每个循环比较，得出是否显示ct值QList<bool>
    QList<QHash<QString, QHash<QString, QString>>> maxAndMinDeltaRn;
    for (int kongWeiCnt = 0; kongWeiCnt < 32; kongWeiCnt++) { // 赋初值
        QHash<QString, QString> yuZhiHashTmp;
        QHash<QString, QHash<QString, QString>> maxAndMinDeltaRnTmp;
        yuZhiHashTmp.insert("fam", DOUBLE_MIN);
        yuZhiHashTmp.insert("vic", DOUBLE_MIN);
        yuZhiHashTmp.insert("rox", DOUBLE_MIN);
        yuZhiHashTmp.insert("cy5", DOUBLE_MIN);
        maxAndMinDeltaRnTmp.insert("max", yuZhiHashTmp);
        yuZhiHashTmp.clear();
        yuZhiHashTmp.insert("fam", DOUBLE_MAX);
        yuZhiHashTmp.insert("vic", DOUBLE_MAX);
        yuZhiHashTmp.insert("rox", DOUBLE_MAX);
        yuZhiHashTmp.insert("cy5", DOUBLE_MAX);
        maxAndMinDeltaRnTmp.insert("min", yuZhiHashTmp);
        maxAndMinDeltaRn.append(maxAndMinDeltaRnTmp);
    }

    //    for (auto i: maxAndMinDeltaRn) {
    //        LOG << i["max"]["fam"] << i["max"]["vic"] <<i["max"]["rox"] <<i["max"]["cy5"];
    //        LOG << i["min"]["fam"] << i["min"]["vic"] <<i["min"]["rox"] <<i["min"]["cy5"];
    //    }

    //    QElapsedTimer timer;
    //    timer.start();

    // 遍历所有曲线
    int xunHuanCnt = 0;
    for (auto xunHuanValue: renderYingGuang) {  // 遍历每个循环 40
        // LOG << "循环" << xunHuanCnt << "开始" << ">>>>>>>>>>>>>>";
        int kongWeiCnt = 0;
        for (auto kongWei: xunHuanValue) { // 遍历每个孔位 32
            QString keys[] = {"1", "2", "3", "4"};
            QString targetKeys[] = {"fam", "vic", "rox", "cy5"};
            double famTmp, vicTmp, roxTmp, cy5Tmp = 0;
            double* temps[] = {&famTmp, &vicTmp, &roxTmp, &cy5Tmp};
            for (int i = 0; i < 4; i++) {
                if (QString::compare(kongWei[keys[i]], "nan")) { // 正常 比较然后插入
                    //  LOG << i << "正常数字" << kongWei[keys[i]];
                    *temps[i] = kongWei[keys[i]].toDouble();
                } else { // 带有nan的数字，赋0然后比较
                    //  LOG << i << "非正常数字" << kongWei[keys[i]];
                    *temps[i] = 0;
                }
            }
            // debug用 LOG<< "循环-"<<  xunHuanCnt << "孔位-" << kongWeiCnt << " " << *temps[0] << *temps[1] << *temps[2] << *temps[3];
            // 与孔位比较存储最大最小值
            for (int i = 0; i < 4 ; i++) {
                if (*temps[i] > maxAndMinDeltaRn[kongWeiCnt]["max"][targetKeys[i]].toDouble())
                    maxAndMinDeltaRn[kongWeiCnt]["max"][targetKeys[i]] = QString::number(*temps[i]);
                if (*temps[i] < maxAndMinDeltaRn[kongWeiCnt]["min"][targetKeys[i]].toDouble())
                    maxAndMinDeltaRn[kongWeiCnt]["min"][targetKeys[i]] = QString::number(*temps[i]);
            }

//            QHash<QString, QString>::iterator deltaRn; // 每个target孔位在每次循环时的deltaRn值
//            for (deltaRn = kongWei.begin(); deltaRn != kongWei.end(); deltaRn++) {
//                LOG << "循环" << xunHuanCnt << "------ 孔位" << kongWeiCnt  << "------------ 靶基因deltaRn值 "
//                            << deltaRn.key() << deltaRn.value(); // 此处存储所有曲线的值 "4" "2792.78" || "2" "0"
//            }
            // LOG << "当前孔位结束------------------(" << kongWeiCnt + 1 << ") / 32";
            kongWeiCnt++;
        }
        xunHuanCnt++;
    }


//    // 打印最大最小值
//    int tmp = 0;
//    for (auto i: maxAndMinDeltaRn) {
//        LOG <<"=-==--------------" <<tmp;
//        LOG <<"max" <<  i["max"]["fam"] << i["max"]["vic"] <<i["max"]["rox"] <<i["max"]["cy5"];
//        LOG <<"min" <<  i["min"]["fam"] << i["min"]["vic"] <<i["min"]["rox"] <<i["min"]["cy5"];
//        tmp++;
//    }

    // 写入yuZhiLineFilterCt
    QList<bool> yuZhiLineFilterCt; // 阈值线超过曲线过滤ct值 128
    QString targetKeys[] = {"fam", "vic", "rox", "cy5"};
    for(auto i : maxAndMinDeltaRn) {
        for (const auto & targetKey : targetKeys) {
//            debug 用 LOG <<i["min"][targetKey].toDouble() << this->yuZhiHash[targetKey] << i["max"][targetKey].toDouble();
            if(i["min"][targetKey].toDouble() < this->yuZhiHash[targetKey] && this->yuZhiHash[targetKey] < i["max"][targetKey].toDouble())
                yuZhiLineFilterCt.append(true);
            else
                yuZhiLineFilterCt.append(false);
        }
    }
    renderRplateCts(this->ct, yuZhiLineFilterCt);


//    LOG << yuZhiLineFilterCt.count() << " " << maxAndMinDeltaRn.count();
//
//    int j = 0;
//    for(auto i : yuZhiLineFilterCt) {
//        LOG << j  << " "<< i;
//        j++;
//    }
//    j = 0;

    //    int elapsed = timer.elapsed();
    //    LOG << "代码运行时间" << elapsed;

}

/* 写入数据分析所用的靶基因 */
QList<AnalysisTarget> ExperimentResultUi::setAnalysisTargetData(QList<QHash<QString, QString>> targetNameList, QHash<QString, double> yuZhiHash, QList<QHash<QString, int>> baseLineList){
    /* 根据靶基因的名称数组数量，来渲染靶基因 */
    int listSize = targetNameList.size(); // 靶基因名称数组数量
    QList<AnalysisTarget> res;

    for(int i = 0; i < listSize; i++){
        AnalysisTarget alysTar; // 实例化数据分析靶基因
        QString reporterKey = ""; // 靶基因key

        /* 提取靶基因名称的key */
        if(targetNameList[i].keys().size() == 1){
            reporterKey = (targetNameList[i].keys())[0];
        }else {
            reporterKey = "";
        }
        alysTar.id = i; // 写入id
        alysTar.targetName = targetNameList[i][reporterKey]; // 写入靶基因名
        alysTar.reporter = reporterKey; // 写入报告基因名
        alysTar.yuZhi = QString::number(yuZhiHash[reporterKey], 'f', 2); // 写入阈值
        for(int j = 0; j < baseLineList.size(); j++){ // 写入基线
            alysTar.jiXianStart = QString::number(baseLineList[j]["start"]);
            alysTar.jiXianEnd = QString::number(baseLineList[j]["end"]);
        }
        // 初始化自动阈值基线状态
        alysTar.autoYuZhiOn = true;
        alysTar.autoJiXianOn = true;

        res.append(alysTar); // 添加靶基因
    }


    return res;

}


/* 更新数据分析所用的靶基因 */
void ExperimentResultUi::updateAnalysisTargetData(QList<QHash<QString, QString>> targetNameList, QHash<QString, double> yuZhiHash, QList<QHash<QString, int>> baseLineList){
    int listSize = this->alysTar.size(); // 靶基因名称数组数量
    for(int i = 0; i < listSize; i++){
        QString reporterKey = ""; // 靶基因key

        /* 提取靶基因名称的key */
        if(targetNameList[i].keys().size() == 1){
            reporterKey = (targetNameList[i].keys())[0];
        }else {
            reporterKey = "";
        }
        this->alysTar[i].targetName = targetNameList[i][reporterKey]; // 写入靶基因名
        this->alysTar[i].reporter = reporterKey; // 写入报告基因名
        this->alysTar[i].yuZhi = QString::number(yuZhiHash[reporterKey], 'f', 2); // 写入阈值
        // 写入基线
        this->alysTar[i].jiXianStart = QString::number(baseLineList[i]["start"]);
        this->alysTar[i].jiXianEnd = QString::number(baseLineList[i]["end"]);
    }
}

/* todo 拆分靶基因数据到各个变量 */
void ExperimentResultUi::splitTargetToValues(QList<AnalysisTarget> alysTar){
    int tarListSize = alysTar.size(); // 靶基因列表大小
    // 开始遍历，拆分到每个数据列表中
    for(int i = 0; i < tarListSize; i++){
        // 阈值
        QString reporter = alysTar[i].reporter;
        this->yuZhiHash[reporter] = alysTar[i].yuZhi.toDouble();

        // 基线
        this->baseLineList[i]["start"] = alysTar[i].jiXianStart.toInt(); // 开始循环数
        this->baseLineList[i]["end"] = alysTar[i].jiXianEnd.toInt(); // 结束循环数
    }
}

/* 渲染结果曲线 */
void ExperimentResultUi::renderResultCurve(){
    this->xSeries = -1;
    this->yAxisMaximum = this->initYAxisMaxmum;

    /* 设置纵轴名称 */
    if(isDeltaRn){
        this->resultYAxis->setTitleText("ΔRn");
    }else {
        this->resultYAxis->setTitleText("Rn");
    }

//        DEV_ENV this->saveYingguangDataList = dAlys->PROCshengcheng(40); // 获取虚拟数值（开发环境）
//        DEV_ENV this->saveYingguangDataListDuplicate = dAlys->PROCshengcheng(40); // 获取虚拟数值（开发环境）

    if(this->saveYingguangDataList.size() != 0){ // 曲线不为空
        this->yAxisMaximum = 0; // 设置y轴最大值为0

        this->clearResultCurve(); // 清空曲线
        this->clearYuZhi(); // 清空阈值

        /* 调用数据分析函数 */
        this->saveYingguangDataList = this->saveYingguangDataListDuplicate; // 重置荧光数据
        this->dataAnalysis();
        /* 渲染曲线 */
        for(int i = 0; i < renderYingGuang.size(); i++){
            this->xSeries++;
            yingGuangData = renderYingGuang[i];
            for(int j = 0; j < yingGuangData.size(); j++){
                int targetCount = sizeof(reactionPlate.targetList[j])/sizeof(Target); // 获取靶基因数量
                for(int k = 0; k < targetCount; k++){ // 获取靶基因，渲染曲线
                    if(reactionPlate.targetList[j][k].reporter == "FAM"){
                        resFamSeriesList[j]->append(xSeries, yingGuangData[j]["1"].toDouble()); // 设置数据
                    }
                    else if (reactionPlate.targetList[j][k].reporter == "VIC") {
                        resVicSeriesList[j]->append(xSeries, yingGuangData[j]["2"].toDouble()); // 设置数据
                    }
                    else if (reactionPlate.targetList[j][k].reporter == "ROX") {
                        resRoxSeriesList[j]->append(xSeries, yingGuangData[j]["3"].toDouble()); // 设置数据
                    }
                    else if (reactionPlate.targetList[j][k].reporter == "CY5") {
                        resCy5SeriesList[j]->append(xSeries, yingGuangData[j]["4"].toDouble()); // 设置数据
                    }
                    resultChart->update();
                }
            }
        }
        isChartInit = false; // 不是图表的初始状态
    }
    /* 非归一化情况下，纵轴刻度渲染 */
    this->yAxisTickRender(isChartInit, isGuiYi);
    LOG << "曲线渲染结束";
}

/* 渲染曲线：对数图 */
void ExperimentResultUi::logarithmCurve(){
    this->clearResultCurve();
    this->xSeries = -1;
    this->yAxisMaximum = this->initYAxisMaxmum;

    //    DEV_ENV this->saveYingguangDataList = dAlys->PROCshengcheng(41); // 获取虚拟数值（开发环境）

    if(this->saveYingguangDataList.size() != 0){ // 曲线不为空
        int coefficient; // 比例系数
        // 根据设定，调整比例系数
        if(ui->yuanShiRn->checkState() == Qt::Checked){ // 如果是原始rn
            coefficient = 1; // 值较大，比例系数小
        }else {
            coefficient = 10; // 值较小，比例系数大
        }
        this->yAxisMaximum = 0; // 设置y轴最大值为0

        this->clearResultCurve(); // 清空曲线
        this->clearYuZhi(); // 清空阈值
        /* 调用数据分析函数 */
        this->dataAnalysis();
        /* 渲染曲线 */
        for(int i = 0; i < renderYingGuang.size(); i++){
            this->xSeries++;
            yingGuangData = renderYingGuang[i];
            for(int j = 0; j < yingGuangData.size(); j++){
                int targetCount = sizeof(reactionPlate.targetList[j])/sizeof(Target); // 获取靶基因数量
                for(int k = 0; k < targetCount; k++){ // 获取靶基因，渲染曲线
                    if(reactionPlate.targetList[j][k].reporter == "FAM"){
                        resFamSeriesList[j]->append(xSeries, yingGuangData[j]["1"].toDouble()*coefficient); // 设置数据
                    }
                    else if (reactionPlate.targetList[j][k].reporter == "VIC") {
                        resVicSeriesList[j]->append(xSeries, yingGuangData[j]["2"].toDouble()*coefficient); // 设置数据
                    }
                    else if (reactionPlate.targetList[j][k].reporter == "ROX") {
                        resRoxSeriesList[j]->append(xSeries, yingGuangData[j]["3"].toDouble()*coefficient); // 设置数据
                    }
                    else if (reactionPlate.targetList[j][k].reporter == "CY5") {
                        resCy5SeriesList[j]->append(xSeries, yingGuangData[j]["4"].toDouble()*coefficient); // 设置数据
                    }
                    resultChart->update();
                }
            }
        }
        //        isChartInit = false; // 不是图表的初始状态
    }
    /* 对数图纵轴刻度渲染 */
    this->logarithmYAxisTickRender();
}

/* 纵轴刻度渲染 */
void ExperimentResultUi::yAxisTickRender(bool isInit, bool isGuiYi){
    // 默认y轴显示
    this->resultYAxis->show();
    // 隐藏对数图的轴线
    this->logarithmYAxis->hide();

    if(isGuiYi){
        return; // 为归一化状态，直接返回
    }

    LOG << "this->yAxisMaximum" << this->yAxisMaximum;

//    this->yAxisMaximum = 1250;

    int yUnit = 0; // y轴单格单元值(不算原点，分为8个单元格)
    int calYMax = 0; // 计算后的y轴最大值

    if(isInit){ // 初始化形式
        yUnit = this->yAxisMaximum / 8;
    }
    else { // 非初始化：正常计算
        /* 计算单元值：低位保留 两个0 */
        yUnit = ceil(this->yAxisMaximum / 8.0);
        yUnit = ceil(yUnit / 100.0) * 100;
    }

    // 最大值为yUnit乘8
    calYMax = yUnit * 8;

    this->resultYAxis->setLabelFormat("%d"); // 设置坐标轴标签格式
    this->resultYAxis->setTickType(QValueAxis::TickType::TicksDynamic);// 设置动态数据
    this->resultYAxis->setTickAnchor(0); // 设置锚点为0
    this->resultYAxis->setRange(0, calYMax); // 纵轴渲染最大值
    this->resultYAxis->setTickInterval(yUnit); // 设置纵轴刻度
}

/* 对数图纵轴刻度渲染 */
void ExperimentResultUi::logarithmYAxisTickRender(){
    // 默认y轴隐藏
    this->resultYAxis->hide();
    // 设置y轴范围
    resultYAxis->setRange(0, logarithmYMaxiMum);
    // 显示对数图的轴线
    this->logarithmYAxis->show();
}

/* 渲染结果页面反应板 */
void ExperimentResultUi::renderResultTable(){
    /* 清空反应板 */
    ui->resultTable->clear();
    /* 清空列表反应板 */
    //    ui->resultDetailTable->clear();
    ui->resultDetailTable->setSortingEnabled(false);

    readAndRenderTableRowColumnFromXML();
    /* 渲染反应板 */
    updateTable();

    /* 渲染列表格式反应板 */
    QList<QString> reporterBox;

    LOG << "targetLegend" << targetLegend;

    /* 根据所选的不为空的图例，更新结果页面详情反应板靶基因信息 */
    for(int l = 0; l < targetLegend.size(); l ++){
        reporterBox.append(targetLegend[QString::number(l+1)]);
    }

    int row = sampleTableRowColumn[0];
    int column = sampleTableRowColumn[1];

    for(int l = 0; l < column * row; l ++){
        for(int i = 0; i < reporterBox.length(); i ++){
            if(reactionPlate.targetList[l][i].name == "null"){
                //                break;
            }
            else{
                int allRow = reporterBox.length() * column * row;
                ui->resultDetailTable->setRowCount(allRow);

                int acolumn = l / row;
                int arow = l % row;

                QString aitem;
                QString label;
                if(arow == 0){label = "A";}
                if(arow == 1){label = "B";}
                if(arow == 2){label = "C";}
                if(arow == 3){label = "D";}
                if(arow == 4){label = "E";}
                if(arow == 5){label = "F";}
                if(arow == 6){label = "G";}
                if(arow == 7){label = "H";}

                aitem = label + QString::number(acolumn + 1);
                QTableWidgetItem *item = new QTableWidgetItem(aitem);
                ui->resultDetailTable->setItem(l * reporterBox.length() + i, 0, item);

                /* 如果靶基因有数据，则该id列数据有值，且值对应着反应板初始时的排序（从0开始） */
                ui->resultDetailTable->setItem(l * reporterBox.length() + i, 6, new QTableWidgetItem(QString::number(l * reporterBox.length() + i)));

            }
            if(reactionPlate.sampleList[l].name != "null"){
                QTableWidgetItem *name = new QTableWidgetItem(reactionPlate.sampleList[l].name);
                ui->resultDetailTable->setItem(l * reporterBox.length() + i, 1, name);

                int allRow = reporterBox.length() * column * row;
                ui->resultDetailTable->setRowCount(allRow);

                int acolumn = l / row;
                int arow = l % row;

                QString aitem;
                QString label;
                if(arow == 0){label = "A";}
                if(arow == 1){label = "B";}
                if(arow == 2){label = "C";}
                if(arow == 3){label = "D";}
                if(arow == 4){label = "E";}
                if(arow == 5){label = "F";}
                if(arow == 6){label = "G";}
                if(arow == 7){label = "H";}

                aitem = label + QString::number(acolumn + 1);
                QTableWidgetItem *item = new QTableWidgetItem(aitem);
                ui->resultDetailTable->setItem(l * reporterBox.length() + i, 0, item);

                /* 如果靶基因有数据，则该id列数据有值，且值对应着反应板初始时的排序（从0开始） */
                QTableWidgetItem *idItem = ui->resultDetailTable->item(l * reporterBox.length() + i, 6);

                if(!idItem || idItem->text() == ""){
                    ui->resultDetailTable->setItem(l * reporterBox.length() + i, 6, new QTableWidgetItem(QString::number(l * reporterBox.length() + i)));
                }
            }
            if(reactionPlate.targetList[l][i].name != "null"){
                QTableWidgetItem *name = new QTableWidgetItem(reactionPlate.targetList[l][i].name);
                ui->resultDetailTable->setItem(l * reporterBox.length() + i, 2, name);
            }
            if(reactionPlate.targetList[l][i].type != "null"){
                QTableWidgetItem *type = new QTableWidgetItem(reactionPlate.targetList[l][i].type);
                ui->resultDetailTable->setItem(l * reporterBox.length() + i, 3, type);
            }
            if(reactionPlate.targetList[l][i].quantity != "null"){
                QTableWidgetItem *quantity = new QTableWidgetItem(reactionPlate.targetList[l][i].quantity);
                ui->resultDetailTable->setItem(l * reporterBox.length() + i, 4, quantity);
            }
            if(reactionPlate.targetList[l][i].explain != "null"){
                QTableWidgetItem *explain = new QTableWidgetItem(reactionPlate.targetList[l][i].explain);
                ui->resultDetailTable->setItem(l * reporterBox.length() + i, 5, explain);
            }
        }
    }

    ui->resultDetailTable->setSortingEnabled(true);

}

/* 清空曲线 */
void ExperimentResultUi::clearResultCurve(){
    if(this->renderYingGuang.size() != 0){
        for(int i = 0; i < 96; i++){
            /* 清除曲线 */
            resCy5SeriesList[i]->clear();
            resFamSeriesList[i]->clear();
            resRoxSeriesList[i]->clear();
            resVicSeriesList[i]->clear();
        }
    }
}

/* 清空阈值线相关信息 */
void ExperimentResultUi::clearYuZhi(){
    /* 清除阈值线 */
    QList<QString> yuZhiKeys = this->yuZhiSeries.keys();
    for(QString key : yuZhiKeys){
        this->yuZhiSeries[key]->clear();
    }
    /* 图表清除函数 */
    this->resultChart->clear();
}


void ExperimentResultUi::readAndRenderTableRowColumnFromXML(){
    configService = new ConfigFileService();

    dyeFromConfig = configService->getDyes();
    QString consume = reactionPlate.consumables;
    sampleTableRowColumn = configService->getRowAndColByConsumableType(consume);
    int row = sampleTableRowColumn[0];
    int column = sampleTableRowColumn[1];

    if(row != 8){
        column = 2;
        row = 8;
    }

    /* 渲染sampleTable */
    ui->resultTable->clear();
    ui->resultTable->setVerticalHeaderLabels(QStringList() << "A" << "B" << "C" << "D" << "E" << "F" << "G" << "H");
    for(int m = 0; m < row; m ++){
        for(int n = column; n < 12; n ++){
            QTableWidgetItem *newItem = new QTableWidgetItem();
            newItem->setFlags(newItem->flags() & ~Qt::ItemIsSelectable);
            ui->resultTable->setItem(m, n, newItem);
            QTableWidgetItem *item = ui->resultTable->item(m, n);
            item->setFlags(item->flags() & ~Qt::ItemIsEnabled & ~Qt::ItemIsSelectable);
            ui->resultTable->setColumnHidden(n, true);
        }
    }
    for(int m = 0; m < row; m ++){
        for(int n = 0; n < column; n ++){
            /* 不隐藏列 */
            ui->resultTable->setColumnHidden(n, false);
        }
    }



    /* 渲染detailTable */
    ui->resultDetailTable->clearContents();
    QList<QString> reporterBox;
    QList<QString> quencherBox;

    for(int l = 0; l < dyeFromConfig.length(); l ++){
        if(dyeFromConfig[l]["type"] == "报告基因"){
            reporterBox.append(dyeFromConfig[l]["name"]);
        }
        else if(dyeFromConfig[l]["type"] == "淬火基因"){
            quencherBox.append(dyeFromConfig[l]["name"]);
        }
    }

    allDyeInfos = dyeLibrary->show();
    for(int i = 0; i < allDyeInfos.size(); i++){
        QHash<QString, QString> dyeInfo = allDyeInfos[i];

        if(dyeInfo["type"] == "二者皆是"){
            int fl = 0;
            for(int m = 0; m < reporterBox.length(); m ++){
                if(dyeInfo["name"] == reporterBox[m]){
                    fl = 1;
                    break;
                }
            }
            if(fl == 0){
                reporterBox.append(dyeInfo["name"]);
            }

            int fll = 0;
            for(int m = 0; m < quencherBox.length(); m ++){
                if(dyeInfo["name"] == quencherBox[m]){
                    fll = 1;
                    break;
                }
            }
            if(fll == 0){
                quencherBox.append(dyeInfo["name"]);
            }
        }
        if(dyeInfo["type"] == "报告基因"){
            int fl = 0;
            for(int m = 0; m < reporterBox.length(); m ++){
                if(dyeInfo["name"] == reporterBox[m]){
                    fl = 1;
                    break;
                }
            }
            if(fl == 0){
                reporterBox.append(dyeInfo["name"]);
            }
        }
        if(dyeInfo["type"] == "淬灭基因"){
            int fll = 0;
            for(int m = 0; m < quencherBox.length(); m ++){
                if(dyeInfo["name"] == quencherBox[m]){
                    fll = 1;
                    break;
                }
            }
            if(fll == 0){
                quencherBox.append(dyeInfo["name"]);
            }
        }
    }
}

void ExperimentResultUi::slot_DL_RcOnTw(QPoint pos)
{
    tableMenu->exec(QCursor::pos());
}


void ExperimentResultUi::slotActionExport(){
    QString filepath = QFileDialog::getSaveFileName(this, tr("Save as..."),
                                                    QString(), tr("EXCEL files (*.xls *.xlsx);;HTML-Files (*.txt);;"));

    if (!filepath.isEmpty()){
        QFile file(filepath);
        bool ret = file.open( QIODevice::Truncate | QIODevice::WriteOnly);
        if(!ret){return;}

        QTextStream stream(&file);
        QString conTents;
        QHeaderView *header = ui->resultDetailTable->horizontalHeader() ;
        if (header){
            for(int i = 0; i < header->count(); i++){
                QTableWidgetItem *item = ui->resultDetailTable->horizontalHeaderItem(i);
                if (!item){continue;}
                conTents += item->text() + " ";
            }
            conTents += "\n";
        }
        for(int i = 0 ; i < ui->resultDetailTable->rowCount(); i++){
            for(int j = 0; j < ui->resultDetailTable->columnCount(); j++){
                QTableWidgetItem *item = ui->resultDetailTable->item(i, j);
                if (!item){continue;}
                QString str = item->text();
                conTents += str + " ";
            }
            conTents += "\n";
        }
        stream << conTents;
        file.close();
    }
}

void ExperimentResultUi::slotActionSave()
{
    //    QString strFile = "孔位信息" + QDateTime::currentDateTime().toString("yyyyMMddHHmmss") + ".png";
    QPixmap pix = QPixmap::grabWidget(ui->resultTable);
    pTool->printEvent(pix, this);

    //    QString fileName = QFileDialog::getSaveFileName(this,"保存图片",strFile,"PNG (*.png);;BMP (*.bmp);;JPEG (*.jpg *.jpeg)");
    //    if (!fileName.isNull())
    //    {
    //        pix.save(fileName);
    //    }
}

/* 获取反应板靶基因数据，对应曲线图例 */
QHash<QString, QString> ExperimentResultUi::getReactionPlateTarget(){
    QHash<QString, QString> targetLegend;
    /* 初始化 */
    targetLegend.clear();
    targetLegendColor1 = "";
    targetLegendColor2 = "";
    targetLegendColor3 = "";
    targetLegendColor4 = "";

    for(int i = 0; i < 96; i++){
        /* 遍历反应孔孔位获取报告基因和对应靶基因名称 */
        QString reporter1 = this->reactionPlate.targetList[i][0].reporter;
        QString reporter2 = this->reactionPlate.targetList[i][1].reporter;
        QString reporter3 = this->reactionPlate.targetList[i][2].reporter;
        QString reporter4 = this->reactionPlate.targetList[i][3].reporter;
        QString name1 = this->reactionPlate.targetList[i][0].name;
        QString name2 = this->reactionPlate.targetList[i][1].name;
        QString name3 = this->reactionPlate.targetList[i][2].name;
        QString name4 = this->reactionPlate.targetList[i][3].name;

        /* 写入报告基因对应靶基因名称 */
        if(reporter1 != "null"){
            if(reporter1 == "FAM" && targetLegend["1"] == ""){
                targetLegend.insert("1", name1);
                targetLegendColor1 = this->reactionPlate.targetList[i][0].color;
                targetReporter1 = reporter1;
            }
            else if(reporter1 == "VIC" && targetLegend["2"] == ""){
                targetLegend.insert("2", name1);
                targetLegendColor2 = this->reactionPlate.targetList[i][0].color;
                targetReporter2 = reporter1;
            }
            else if(reporter1 == "ROX" && targetLegend["3"] == ""){
                targetLegend.insert("3", name1);
                targetLegendColor3 = this->reactionPlate.targetList[i][0].color;
                targetReporter3 = reporter1;
            }
            else if(reporter1 == "CY5" && targetLegend["4"] == ""){
                targetLegend.insert("4", name1);
                targetLegendColor4 = this->reactionPlate.targetList[i][0].color;
                targetReporter4 = reporter1;
            }
        }
        if(reporter2 != "null"){
            if(reporter2 == "FAM" && targetLegend["1"] == ""){
                targetLegend.insert("1", name2);
                targetLegendColor1 = this->reactionPlate.targetList[i][1].color;
                targetReporter1 = reporter2;
            }
            else if(reporter2 == "VIC" && targetLegend["2"] == ""){
                targetLegend.insert("2", name2);
                targetLegendColor2 = this->reactionPlate.targetList[i][1].color;
                targetReporter2 = reporter2;
            }
            else if(reporter2 == "ROX" && targetLegend["3"] == ""){
                targetLegend.insert("3", name2);
                targetLegendColor3 = this->reactionPlate.targetList[i][1].color;
                targetReporter3 = reporter2;
            }
            else if(reporter2 == "CY5" && targetLegend["4"] == ""){
                targetLegend.insert("4", name2);
                targetLegendColor4 = this->reactionPlate.targetList[i][1].color;
                targetReporter4 = reporter2;
            }
        }
        if(reporter3 != "null"){
            if(reporter3 == "FAM" && targetLegend["1"] == ""){
                targetLegend.insert("1", name3);
                targetLegendColor1 = this->reactionPlate.targetList[i][2].color;
                targetReporter1 = reporter3;
            }
            else if(reporter3 == "VIC" && targetLegend["2"] == ""){
                targetLegend.insert("2", name3);
                targetLegendColor2 = this->reactionPlate.targetList[i][2].color;
                targetReporter2 = reporter3;
            }
            else if(reporter3 == "ROX" && targetLegend["3"] == ""){
                targetLegend.insert("3", name3);
                targetLegendColor3 = this->reactionPlate.targetList[i][2].color;
                targetReporter3 = reporter3;
            }
            else if(reporter3 == "CY5" && targetLegend["4"] == ""){
                targetLegend.insert("4", name3);
                targetLegendColor4 = this->reactionPlate.targetList[i][2].color;
                targetReporter4 = reporter3;
            }
        }
        if(reporter4 != "null"){
            if(reporter4 == "FAM" && targetLegend["1"] == ""){
                targetLegend.insert("1", name4);
                targetLegendColor1 = this->reactionPlate.targetList[i][3].color;
                targetReporter1 = reporter4;
            }
            else if(reporter4 == "VIC" && targetLegend["2"] == ""){
                targetLegend.insert("2", name4);
                targetLegendColor2 = this->reactionPlate.targetList[i][3].color;
                targetReporter2 = reporter4;
            }
            else if(reporter4 == "ROX" && targetLegend["3"] == ""){
                targetLegend.insert("3", name4);
                targetLegendColor3 = this->reactionPlate.targetList[i][3].color;
                targetReporter3 = reporter4;
            }
            else if(reporter4 == "CY5" && targetLegend["4"] == ""){
                targetLegend.insert("4", name4);
                targetLegendColor4 = this->reactionPlate.targetList[i][3].color;
                targetReporter4 = reporter4;
            }
        }
        /* 如果QHash四个孔位都不为空，提前退出循环 */
        if(targetLegend["1"] != "" && targetLegend["2"] != "" && targetLegend["3"] != "" && targetLegend["4"] != "")
            break;
    }

    /* 更换图例名称、渲染曲线和图例颜色 */
    // FAM
    if(targetLegend["1"] != ""){
        ui->famLabel->show();
        ui->famBtn->show();
        ui->famLabel->setText(targetLegend["1"] + "("+ targetReporter1 + ")");
        QString styleSheet = "QPushButton {min-width: 10px; max-width: 10px; min-height: 10px; max-height: 10px; border: 1px solid rgba(0,0,0,.5);" "background-color: rgb(" + targetLegendColor1 + ");}";
        ui->famBtn->setStyleSheet(styleSheet);

    }
    else{
        ui->famLabel->hide();
        ui->famBtn->hide();
    }
    // VIC
    if(targetLegend["2"] != ""){
        ui->vicLabel->show();
        ui->vicBtn->show();
        ui->vicLabel->setText(targetLegend["2"] + "("+ targetReporter2 + ")");
        QString styleSheet = "QPushButton {min-width: 10px; max-width: 10px; min-height: 10px; max-height: 10px; border: 1px solid rgba(0,0,0,.5);" "background-color: rgb(" + targetLegendColor2 + ");}";
        ui->vicBtn->setStyleSheet(styleSheet);
    }
    else{
        ui->vicLabel->hide();
        ui->vicBtn->hide();
    }
    // ROX
    if(targetLegend["3"] != ""){
        ui->roxLabel->show();
        ui->roxBtn->show();
        ui->roxLabel->setText(targetLegend["3"] + "("+ targetReporter3 + ")");
        QString styleSheet = "QPushButton {min-width: 10px; max-width: 10px; min-height: 10px; max-height: 10px; border: 1px solid rgba(0,0,0,.5);" "background-color: rgb(" + targetLegendColor3 + ");}";
        ui->roxBtn->setStyleSheet(styleSheet);
    }
    else{
        ui->roxLabel->hide();
        ui->roxBtn->hide();
    }

    // CY5
    if(targetLegend["4"] != ""){
        ui->cy5Label->show();
        ui->cy5Btn->show();
        ui->cy5Label->setText(targetLegend["4"] + "("+ targetReporter4 + ")");
        QString styleSheet = "QPushButton {min-width: 10px; max-width: 10px; min-height: 10px; max-height: 10px; border: 1px solid rgba(0,0,0,.5);" "background-color: rgb(" + targetLegendColor4 + ");}";
        ui->cy5Btn->setStyleSheet(styleSheet);
    }
    else{
        ui->cy5Label->hide();
        ui->cy5Btn->hide();
    }

    /* 设置曲线颜色 */
    for(int i = 0; i < 96; i++){
        if(targetLegendColor1 != ""){
            QStringList tarColor1 = targetLegendColor1.split(",");
            resFamSeriesList[i]->setPen(QPen(QColor(tarColor1[0].toInt(), tarColor1[1].toInt(), tarColor1[2].toInt(), 255),2,Qt::SolidLine)); //设置画笔
            resFamSeriesList[i]->setColor(QColor(tarColor1[0].toInt(), tarColor1[1].toInt(), tarColor1[2].toInt(), 255));  //设置颜色
        }
        else {
            resFamSeriesList[i]->setPen(QPen(QColor(0,0,0,0),2,Qt::SolidLine)); //设置画笔
            resFamSeriesList[i]->setColor(QColor(0,0,0,0));  //设置颜色
        }
        if(targetLegendColor2 != ""){
            QStringList tarColor2 = targetLegendColor2.split(",");
            resVicSeriesList[i]->setPen(QPen(QColor(tarColor2[0].toInt(), tarColor2[1].toInt(), tarColor2[2].toInt(), 255),2,Qt::SolidLine)); //设置画笔
            resVicSeriesList[i]->setColor(QColor(tarColor2[0].toInt(), tarColor2[1].toInt(), tarColor2[2].toInt(), 255));  //设置颜色
        }
        else {
            resVicSeriesList[i]->setPen(QPen(QColor(0,0,0,0),2,Qt::SolidLine)); //设置画笔
            resVicSeriesList[i]->setColor(QColor(0,0,0,0));  //设置颜色
        }
        if(targetLegendColor3 != ""){
            QStringList tarColor3 = targetLegendColor3.split(",");
            resRoxSeriesList[i]->setPen(QPen(QColor(tarColor3[0].toInt(), tarColor3[1].toInt(), tarColor3[2].toInt(), 255),2,Qt::SolidLine)); //设置画笔
            resRoxSeriesList[i]->setColor(QColor(tarColor3[0].toInt(), tarColor3[1].toInt(), tarColor3[2].toInt(), 255));  //设置颜色
        }
        else {
            resRoxSeriesList[i]->setPen(QPen(QColor(0,0,0,0),2,Qt::SolidLine)); //设置画笔
            resRoxSeriesList[i]->setColor(QColor(0,0,0,0));  //设置颜色
        }
        if(targetLegendColor4 != ""){
            QStringList tarColor4 = targetLegendColor4.split(",");
            resCy5SeriesList[i]->setPen(QPen(QColor(tarColor4[0].toInt(), tarColor4[1].toInt(), tarColor4[2].toInt(), 255),2,Qt::SolidLine)); //设置画笔
            resCy5SeriesList[i]->setColor(QColor(tarColor4[0].toInt(), tarColor4[1].toInt(), tarColor4[2].toInt(), 255));  //设置颜色
        }
        else {
            resCy5SeriesList[i]->setPen(QPen(QColor(0,0,0,0),2,Qt::SolidLine)); //设置画笔
            resCy5SeriesList[i]->setColor(QColor(0,0,0,0));  //设置颜色
        }
    }

    return targetLegend;
}

/* 渲染图例样式 */
void ExperimentResultUi::renderLegendStyle(){
    /* 更换图例名称和图例颜色 */
    QString baseStyleSheet = "QPushButton {min-width: 10px; max-width: 10px; min-height: 10px; max-height: 10px; border: 1px solid rgba(0,0,0,.5);";
    // 初始化：将图例都变灰
    QString initStyleSheet = baseStyleSheet + "background-color: rgba(0,0,0,.3);}";
    ui->famBtn->setStyleSheet(initStyleSheet);
    ui->vicBtn->setStyleSheet(initStyleSheet);
    ui->roxBtn->setStyleSheet(initStyleSheet);
    ui->cy5Btn->setStyleSheet(initStyleSheet);

    // 渲染四个可见图例颜色
    // fam
    if(this->famVisible){
        if(targetLegendColor1 != ""){
            /* 改变图例样式 */
            QString styleSheet = "QPushButton {min-width: 10px; max-width: 10px; min-height: 10px; max-height: 10px; border: 1px solid rgba(0,0,0,.5);" "background-color: rgb(" + targetLegendColor1 + ");}";
            ui->famBtn->setStyleSheet(styleSheet);
        }
    }else {
        /* 改变图例样式 */
        QString styleSheet = "QPushButton {min-width: 10px; max-width: 10px; min-height: 10px; max-height: 10px; border: 1px solid rgba(0,0,0,.5);" "background-color: rgba(0,0,0,.3);}";
        ui->famBtn->setStyleSheet(styleSheet);
    }

    // vic
    if(this->vicVisible){
        if(targetLegendColor2 != ""){
            /* 改变图例样式 */
            QString styleSheet = "QPushButton {min-width: 10px; max-width: 10px; min-height: 10px; max-height: 10px; border: 1px solid rgba(0,0,0,.5);" "background-color: rgb(" + targetLegendColor2 + ");}";
            ui->vicBtn->setStyleSheet(styleSheet);
        }
    }else {
        /* 改变图例样式 */
        QString styleSheet = "QPushButton {min-width: 10px; max-width: 10px; min-height: 10px; max-height: 10px; border: 1px solid rgba(0,0,0,.5);" "background-color: rgba(0,0,0,.3);}";
        ui->vicBtn->setStyleSheet(styleSheet);
    }

    // rox
    if(this->roxVisible){
        if(targetLegendColor3 != ""){
            /* 改变图例样式 */
            QString styleSheet = "QPushButton {min-width: 10px; max-width: 10px; min-height: 10px; max-height: 10px; border: 1px solid rgba(0,0,0,.5);" "background-color: rgb(" + targetLegendColor3 + ");}";
            ui->roxBtn->setStyleSheet(styleSheet);
        }
    }else {
        /* 改变图例样式 */
        QString styleSheet = "QPushButton {min-width: 10px; max-width: 10px; min-height: 10px; max-height: 10px; border: 1px solid rgba(0,0,0,.5);" "background-color: rgba(0,0,0,.3);}";
        ui->roxBtn->setStyleSheet(styleSheet);
    }

    // cy5
    if(this->cy5Visible){
        if(targetLegendColor4 != ""){
            /* 改变图例样式 */
            QString styleSheet = "QPushButton {min-width: 10px; max-width: 10px; min-height: 10px; max-height: 10px; border: 1px solid rgba(0,0,0,.5);" "background-color: rgb(" + targetLegendColor4 + ");}";
            ui->cy5Btn->setStyleSheet(styleSheet);
        }
    }else {
        /* 改变图例样式 */
        QString styleSheet = "QPushButton {min-width: 10px; max-width: 10px; min-height: 10px; max-height: 10px; border: 1px solid rgba(0,0,0,.5);" "background-color: rgba(0,0,0,.3);}";
        ui->cy5Btn->setStyleSheet(styleSheet);
    }
}

/* 渲染结果曲线数据样式 */
void ExperimentResultUi::renderLineDataStyle(){
    /* 设置曲线颜色 */
    if(this->saveYingguangDataList.size() != 0){
        for(int i = 0; i < 96; i++){
            // fam
            if(this->famVisible){
                int lineWidth = resFamSeriesList[i]->pen().width(); // 获取曲线宽度
                if(targetLegendColor1 != ""){
                    QStringList tarColor1 = targetLegendColor1.split(",");
                    resFamSeriesList[i]->setPen(QPen(QColor(tarColor1[0].toInt(), tarColor1[1].toInt(), tarColor1[2].toInt(), 255), lineWidth,Qt::SolidLine)); //设置画笔
                }
            }
            else {
                int lineWidth = resFamSeriesList[i]->pen().width(); // 获取曲线宽度
                resFamSeriesList[i]->setPen(QPen(QColor(0,0,0,0), lineWidth,Qt::SolidLine)); //设置画笔

            }

            // vic
            if(this->vicVisible){
                if(targetLegendColor2 != ""){
                    int lineWidth = resVicSeriesList[i]->pen().width(); // 获取曲线宽度
                    QStringList tarColor2 = targetLegendColor2.split(",");
                    resVicSeriesList[i]->setPen(QPen(QColor(tarColor2[0].toInt(), tarColor2[1].toInt(), tarColor2[2].toInt(), 255),lineWidth,Qt::SolidLine)); //设置画笔
                }
            }
            else {
                int lineWidth = resVicSeriesList[i]->pen().width(); // 获取曲线宽度
                resVicSeriesList[i]->setPen(QPen(QColor(0,0,0,0),lineWidth,Qt::SolidLine)); //设置画笔
            }

            // rox
            if(this->roxVisible){
                if(targetLegendColor3 != ""){
                    int lineWidth = resRoxSeriesList[i]->pen().width(); // 获取曲线宽度
                    QStringList tarColor3 = targetLegendColor3.split(",");
                    resRoxSeriesList[i]->setPen(QPen(QColor(tarColor3[0].toInt(), tarColor3[1].toInt(), tarColor3[2].toInt(), 255),lineWidth,Qt::SolidLine)); //设置画笔
                }
            }
            else {
                int lineWidth = resRoxSeriesList[i]->pen().width(); // 获取曲线宽度
                resRoxSeriesList[i]->setPen(QPen(QColor(0,0,0,0),lineWidth,Qt::SolidLine)); //设置画笔

            }

            // cy5
            if(this->cy5Visible){
                if(targetLegendColor4 != ""){
                    int lineWidth = resCy5SeriesList[i]->pen().width(); // 获取曲线宽度
                    QStringList tarColor4 = targetLegendColor4.split(",");
                    resCy5SeriesList[i]->setPen(QPen(QColor(tarColor4[0].toInt(), tarColor4[1].toInt(), tarColor4[2].toInt(), 255),lineWidth,Qt::SolidLine)); //设置画笔
                }
            }
            else {
                int lineWidth = resCy5SeriesList[i]->pen().width(); // 获取曲线宽度
                resCy5SeriesList[i]->setPen(QPen(QColor(0,0,0,0),lineWidth,Qt::SolidLine)); //设置画笔
            }
        }
    }
}

/* 样板表过滤功能 */
void ExperimentResultUi::filter(QAction *action){
    renderResultTable();
}

/* 扩增曲线通道过滤 */
void ExperimentResultUi::curveFilter(QString selector){
    /* 开始下拉框过滤 */
    /* 根据selector反查key的对应类型 */
    QString keyNum = this->targetLegend.key(selector);
    if(keyNum == "1") selector = "FAM";
    else if(keyNum == "2") selector = "VIC";
    else if(keyNum == "3") selector = "ROX";
    else if(keyNum == "4") selector = "CY5";
    else selector = "所有通道";

    // 全关闭
    this->famVisible = false;
    this->vicVisible = false;
    this->roxVisible = false;
    this->cy5Visible = false;

    /* 选择FAM */
    if(selector == "FAM"){
        this->famVisible = true; // 开启fam
    }

    /* 选择VIC */
    if(selector == "VIC"){
        this->vicVisible = true; // 开启vic
    }

    /* 选择ROX */
    if(selector == "ROX"){
        this->roxVisible = true; // 开启rox
    }

    /* 选择CY5 */
    if(selector == "CY5"){
        this->cy5Visible = true; // 开启cy5
    }

    /* 全选 */
    if(selector == "所有通道"){
        // 全开启
        this->famVisible = true;
        this->vicVisible = true;
        this->roxVisible = true;
        this->cy5Visible = true;

    }

    // 渲染曲线样式和图例样式
    this->renderLegendStyle();
    this->renderLineDataStyle();

    /* 如果阈值线显示，则根据下拉列表过滤阈值 */
    if(ui->showYuZhiXian->checkState() == Qt::Checked){
        this->yuZhiLineFilter();
    }

    QItemSelectionModel *selection = ui->resultTable->selectionModel();
    QModelIndexList indexList = selection->selectedIndexes();
    if(indexList.size() != 0){
        this->filterSelectedCurve();
    }

}

/*（使用图例）曲线过滤槽函数 */
void ExperimentResultUi::curveLabelFilter(QString filterNum){
    // 先都开启
    if(ui->channalSelection->currentIndex() != 0){
        ui->channalSelection->blockSignals(true); // 阻断信号
        this->famVisible = true;
        this->vicVisible = true;
        this->roxVisible = true;
        this->cy5Visible = true;
        // 下拉框通道过滤改为全部靶基因
        ui->channalSelection->setCurrentIndex(0);
        ui->channalSelection->blockSignals(false); // 解除阻断
    }

    // 开始设置图例过滤
    switch(filterNum.toInt()){
    case 1: this->famVisible = !this->famVisible; break; // 开启fam
    case 2: this->vicVisible = !this->vicVisible; break; // 开启vic
    case 3: this->roxVisible = !this->roxVisible; break; // 开启rox
    case 4: this->cy5Visible = !this->cy5Visible; break; // 开启cy5
    default:
        // 传入其他：全开启
        this->famVisible = true;
        this->vicVisible = true;
        this->roxVisible = true;
        this->cy5Visible = true;
        break;
    }
    // 渲染曲线样式和图例样式
    this->renderLegendStyle();
    this->renderLineDataStyle();

    /* 如果阈值线显示，则根据下拉列表过滤阈值 */
    if(ui->showYuZhiXian->checkState() == Qt::Checked){
        this->yuZhiLineFilter();
    }

    QItemSelectionModel *selection = ui->resultTable->selectionModel();
    QModelIndexList indexList = selection->selectedIndexes();
    if(indexList.size() != 0){
        this->filterSelectedCurve();
    }
}
void ExperimentResultUi::renderYuzhiSlot(QHash<QString, double> yuZhiHash){
    if(ui->showYuZhiXian->checkState() == Qt::Checked){
        /* 判断阈值合法性后，更新阈值(合法性：判断阈值是否为0) */
        QList<QString> yuZhiKeys = yuZhiHash.keys();
        for(QString key : yuZhiKeys){
            if(this->yuZhiHash[key] == 0.0){ // 如果所选key的阈值不存在，那么hash的值置为0，说明阈值未被选中，即阈值不合法
                this->yuZhiHash[key] = 0.0;
            }else if(yuZhiHash[key] != 0.0) { // 如果阈值合法
                this->yuZhiHash[key] = yuZhiHash[key]; // 更新阈值
            }
        }
        if(ui->logarithm->checkState() == Qt::Checked){ // 选中对数图
            this->logarithmCurve(); // 渲染对数曲线
        }
        else {
            this->renderResultCurve(); // 渲染普通曲线
        }
    }
}
/* 阈值线过滤下拉列表渲染 */
void ExperimentResultUi::yuZhiLineFilter(){
    /* 清空列表 */
    this->validYuZhiList.clear(); // 清空合法阈值
    resultChart->clear(); // 清空图表

    int count = 0;

    /* 开始过滤 */
    // fam
    if(this->famVisible){
        this->validYuZhiList.append("fam"); // 加入合法阈值
        count++;
    }
    // vic
    if(this->vicVisible){
        this->validYuZhiList.append("vic"); // 加入合法阈值
        count++;
    }
    // rox
    if(this->roxVisible){
        this->validYuZhiList.append("rox"); // 加入合法阈值
        count++;
    }
    // cy5
    if(this->cy5Visible){
        this->validYuZhiList.append("cy5"); // 加入合法阈值
        count++;
    }
    LOG << yuZhiSeries.size();
    LOG << count;

    /* 当选中所有通道时解绑ccview的双击编辑 */
    if(count == yuZhiSeries.size()){
        this->resultChart->disconnectDoubleClickEvent();
    }
    else{
        this->resultChart->connectDoubleClickEvent();
    }

    LOG << "this->validYuZhiListthis->validYuZhiList" << this->validYuZhiList;

    if(ui->logarithm->checkState() == Qt::Checked){ // 选中对数图
        this->logarithmCurve();
    }else { // 普通曲线
        this->renderResultCurve();
    }
}

/* 扩增曲线过滤下拉列表渲染 */
void ExperimentResultUi::renderFilterList(){
    /* 清空列表 */
    ui->channalSelection->clear();
    /* 添加全选中条件 */
    ui->channalSelection->addItem("所有通道");
    /* 根据this->targetLegend的value来添加列表的靶基因 */
    if(this->targetLegend.value("1") != "")
        ui->channalSelection->addItem(this->targetLegend.value("1"));
    if(this->targetLegend.value("2") != "")
        ui->channalSelection->addItem(this->targetLegend.value("2"));
    if(this->targetLegend.value("3") != "")
        ui->channalSelection->addItem(this->targetLegend.value("3"));
    if(this->targetLegend.value("4") != "")
        ui->channalSelection->addItem(this->targetLegend.value("4"));
}

/* 过滤选中的反应板的曲线 */
void ExperimentResultUi::filterSelectedCurve(){
    /* 重置所有曲线 */
    for(int i = 0; i < 96; i++){
        // fam
        int lineWidth = resFamSeriesList[i]->pen().width(); // 获取曲线宽度
        if(targetLegendColor1 != ""){
            QStringList tarColor1 = targetLegendColor1.split(",");
            resFamSeriesList[i]->setPen(QPen(QColor(tarColor1[0].toInt(), tarColor1[1].toInt(), tarColor1[2].toInt(), 0), lineWidth,Qt::SolidLine)); //设置画笔
        }
        // vic
        if(targetLegendColor2 != ""){
            int lineWidth = resVicSeriesList[i]->pen().width(); // 获取曲线宽度
            QStringList tarColor2 = targetLegendColor2.split(",");
            resVicSeriesList[i]->setPen(QPen(QColor(tarColor2[0].toInt(), tarColor2[1].toInt(), tarColor2[2].toInt(), 0),lineWidth,Qt::SolidLine)); //设置画笔
        }
        // rox
        if(targetLegendColor3 != ""){
            int lineWidth = resRoxSeriesList[i]->pen().width(); // 获取曲线宽度
            QStringList tarColor3 = targetLegendColor3.split(",");
            resRoxSeriesList[i]->setPen(QPen(QColor(tarColor3[0].toInt(), tarColor3[1].toInt(), tarColor3[2].toInt(), 0),lineWidth,Qt::SolidLine)); //设置画笔
        }
        // cy5
        if(targetLegendColor4 != ""){
            int lineWidth = resCy5SeriesList[i]->pen().width(); // 获取曲线宽度
            QStringList tarColor4 = targetLegendColor4.split(",");
            resCy5SeriesList[i]->setPen(QPen(QColor(tarColor4[0].toInt(), tarColor4[1].toInt(), tarColor4[2].toInt(), 0),lineWidth,Qt::SolidLine)); //设置画笔
        }
    }

    QItemSelectionModel *selection = ui->resultTable->selectionModel();
    QModelIndexList indexList = selection->selectedIndexes();

    // 发送改变选中的反应版背景颜色信号
    emit ExperimentResultUi::changeRpItemBgColor(indexList);

    /* 获取选中的行列数 */
    foreach(QModelIndex index, indexList){
        /* 将行列数转化为数组下标 */
        int row = index.row();
        int column = index.column();
        int tableIndex = row + column*8;

        /* 将曲线显示 */
        // fam
        if(this->famVisible){
            int lineWidth = resFamSeriesList[tableIndex]->pen().width(); // 获取曲线宽度
            if(targetLegendColor1 != ""){
                QStringList tarColor1 = targetLegendColor1.split(",");
                resFamSeriesList[tableIndex]->setPen(QPen(QColor(tarColor1[0].toInt(), tarColor1[1].toInt(), tarColor1[2].toInt(), 255), lineWidth,Qt::SolidLine)); //设置画笔
            }
        }
        else {
            int lineWidth = resFamSeriesList[tableIndex]->pen().width(); // 获取曲线宽度
            resFamSeriesList[tableIndex]->setPen(QPen(QColor(0,0,0,0), lineWidth,Qt::SolidLine)); //设置画笔

        }

        // vic
        if(this->vicVisible){
            if(targetLegendColor2 != ""){
                int lineWidth = resVicSeriesList[tableIndex]->pen().width(); // 获取曲线宽度
                QStringList tarColor2 = targetLegendColor2.split(",");
                resVicSeriesList[tableIndex]->setPen(QPen(QColor(tarColor2[0].toInt(), tarColor2[1].toInt(), tarColor2[2].toInt(), 255),lineWidth,Qt::SolidLine)); //设置画笔
            }
        }
        else {
            int lineWidth = resVicSeriesList[tableIndex]->pen().width(); // 获取曲线宽度
            resVicSeriesList[tableIndex]->setPen(QPen(QColor(0,0,0,0),lineWidth,Qt::SolidLine)); //设置画笔
        }

        // rox
        if(this->roxVisible){
            if(targetLegendColor3 != ""){
                int lineWidth = resRoxSeriesList[tableIndex]->pen().width(); // 获取曲线宽度
                QStringList tarColor3 = targetLegendColor3.split(",");
                resRoxSeriesList[tableIndex]->setPen(QPen(QColor(tarColor3[0].toInt(), tarColor3[1].toInt(), tarColor3[2].toInt(), 255),lineWidth,Qt::SolidLine)); //设置画笔
            }
        }
        else {
            int lineWidth = resRoxSeriesList[tableIndex]->pen().width(); // 获取曲线宽度
            resRoxSeriesList[tableIndex]->setPen(QPen(QColor(0,0,0,0),lineWidth,Qt::SolidLine)); //设置画笔

        }

        // cy5
        if(this->cy5Visible){
            if(targetLegendColor4 != ""){
                int lineWidth = resCy5SeriesList[tableIndex]->pen().width(); // 获取曲线宽度
                QStringList tarColor4 = targetLegendColor4.split(",");
                resCy5SeriesList[tableIndex]->setPen(QPen(QColor(tarColor4[0].toInt(), tarColor4[1].toInt(), tarColor4[2].toInt(), 255),lineWidth,Qt::SolidLine)); //设置画笔
            }
        }
        else {
            int lineWidth = resCy5SeriesList[tableIndex]->pen().width(); // 获取曲线宽度
            resCy5SeriesList[tableIndex]->setPen(QPen(QColor(0,0,0,0),lineWidth,Qt::SolidLine)); //设置画笔
        }
    }
}

/* 加粗详细表选中的曲线 */
void ExperimentResultUi::boldCurve(){
    /* 重置所有曲线 */
    for(int i = 0; i < 96; i++){
        if(this->targetLegendColor1 != ""){
            int lineFamAlpha = resFamSeriesList[i]->color().alpha();
            QStringList tarColor1 = this->targetLegendColor1.split(",");
            resFamSeriesList[i]->setPen(QPen(QColor(tarColor1[0].toInt(), tarColor1[1].toInt(), tarColor1[2].toInt(), lineFamAlpha),2,Qt::SolidLine)); //设置画笔
        }
        if(this->targetLegendColor2 != ""){
            int lineVicAlpha = resVicSeriesList[i]->color().alpha();
            QStringList tarColor2 = this->targetLegendColor2.split(",");
            resVicSeriesList[i]->setPen(QPen(QColor(tarColor2[0].toInt(), tarColor2[1].toInt(), tarColor2[2].toInt(), lineVicAlpha),2,Qt::SolidLine)); //设置画笔
        }
        if(this->targetLegendColor3 != ""){
            int lineRoxAlpha = resRoxSeriesList[i]->color().alpha();
            QStringList tarColor3 = this->targetLegendColor3.split(",");
            resRoxSeriesList[i]->setPen(QPen(QColor(tarColor3[0].toInt(), tarColor3[1].toInt(), tarColor3[2].toInt(), lineRoxAlpha),2,Qt::SolidLine)); //设置画笔
        }
        if(this->targetLegendColor4 != ""){
            int lineCy5Alpha = resCy5SeriesList[i]->color().alpha();
            QStringList tarColor4 = this->targetLegendColor4.split(",");
            resCy5SeriesList[i]->setPen(QPen(QColor(tarColor4[0].toInt(), tarColor4[1].toInt(), tarColor4[2].toInt(), lineCy5Alpha),2,Qt::SolidLine)); //设置画笔
        }
    }

    // 获取选中的行
    QItemSelectionModel *selection = ui->resultDetailTable->selectionModel();
    QModelIndexList rowsList = selection->selectedRows();
    // 曲线宽度
    int lineWidth = 6;

    /* 获取选中的行列数 */
    foreach(QModelIndex rowIndex, rowsList){
        // 获取选中行行id
        int row = rowIndex.row(); // 行
        int rowId = (ui->resultDetailTable->item(row, 6) && ui->resultDetailTable->item(row, 6)->text() != "") ? (ui->resultDetailTable->item(row, 6)->text().toInt()) : -1;
        int selectedTarget = rowId % 4; // 获取当前选中的靶基因
        int selectedTarget2CurSeries = rowId/4; // 获取选中的靶基因是当前曲线的第几个

        if(rowId == -1){ // 行下标不合法或不存在
            return;
        }

        /* 将曲线加粗 */
        if(this->targetLegendColor1 != "" && selectedTarget == 0){
            int lineFamAlpha = resFamSeriesList[selectedTarget2CurSeries]->color().alpha();
            QStringList tarColor1 = this->targetLegendColor1.split(",");
            resFamSeriesList[selectedTarget2CurSeries]->setPen(QPen(QColor(tarColor1[0].toInt(), tarColor1[1].toInt(), tarColor1[2].toInt(), lineFamAlpha),lineWidth,Qt::SolidLine)); //设置画笔
        }
        if(this->targetLegendColor2 != "" && selectedTarget == 1){
            int lineVicAlpha = resVicSeriesList[selectedTarget2CurSeries]->color().alpha();
            QStringList tarColor2 = this->targetLegendColor2.split(",");
            resVicSeriesList[selectedTarget2CurSeries]->setPen(QPen(QColor(tarColor2[0].toInt(), tarColor2[1].toInt(), tarColor2[2].toInt(), lineVicAlpha),lineWidth,Qt::SolidLine)); //设置画笔
        }
        if(this->targetLegendColor3 != "" && selectedTarget == 2){
            int lineRoxAlpha = resRoxSeriesList[selectedTarget2CurSeries]->color().alpha();
            QStringList tarColor3 = this->targetLegendColor3.split(",");
            resRoxSeriesList[selectedTarget2CurSeries]->setPen(QPen(QColor(tarColor3[0].toInt(), tarColor3[1].toInt(), tarColor3[2].toInt(), lineRoxAlpha),lineWidth,Qt::SolidLine)); //设置画笔
        }
        if(this->targetLegendColor4 != "" && selectedTarget == 3){
            int lineCy5Alpha = resCy5SeriesList[selectedTarget2CurSeries]->color().alpha();
            QStringList tarColor4 = this->targetLegendColor4.split(",");
            resCy5SeriesList[selectedTarget2CurSeries]->setPen(QPen(QColor(tarColor4[0].toInt(), tarColor4[1].toInt(), tarColor4[2].toInt(), lineCy5Alpha),lineWidth,Qt::SolidLine)); //设置画笔
        }
    }
}

void ExperimentResultUi::unboldCurve(){
    /* 重置所有曲线 */
    for(int i = 0; i < 96; i++){
        if(this->targetLegendColor1 != ""){
            int lineFamAlpha = resFamSeriesList[i]->color().alpha();
            QStringList tarColor1 = this->targetLegendColor1.split(",");
            resFamSeriesList[i]->setPen(QPen(QColor(tarColor1[0].toInt(), tarColor1[1].toInt(), tarColor1[2].toInt(), lineFamAlpha),2,Qt::SolidLine)); //设置画笔
        }
        if(this->targetLegendColor2 != ""){
            int lineVicAlpha = resVicSeriesList[i]->color().alpha();
            QStringList tarColor2 = this->targetLegendColor2.split(",");
            resVicSeriesList[i]->setPen(QPen(QColor(tarColor2[0].toInt(), tarColor2[1].toInt(), tarColor2[2].toInt(), lineVicAlpha),2,Qt::SolidLine)); //设置画笔
        }
        if(this->targetLegendColor3 != ""){
            int lineRoxAlpha = resRoxSeriesList[i]->color().alpha();
            QStringList tarColor3 = this->targetLegendColor3.split(",");
            resRoxSeriesList[i]->setPen(QPen(QColor(tarColor3[0].toInt(), tarColor3[1].toInt(), tarColor3[2].toInt(), lineRoxAlpha),2,Qt::SolidLine)); //设置画笔
        }
        if(this->targetLegendColor4 != ""){
            int lineCy5Alpha = resCy5SeriesList[i]->color().alpha();
            QStringList tarColor4 = this->targetLegendColor4.split(",");
            resCy5SeriesList[i]->setPen(QPen(QColor(tarColor4[0].toInt(), tarColor4[1].toInt(), tarColor4[2].toInt(), lineCy5Alpha),2,Qt::SolidLine)); //设置画笔
        }
    }

    // 获取选中的行
    QItemSelectionModel *selection = ui->resultDetailTable->selectionModel();
    QModelIndexList rowsList = selection->selectedRows();
    // 曲线宽度
    int lineWidth = 2;

    /* 获取选中的行列数 */
    foreach(QModelIndex rowIndex, rowsList){
        // 获取选中行行id
        int row = rowIndex.row(); // 行
        int rowId = (ui->resultDetailTable->item(row, 6) && ui->resultDetailTable->item(row, 6)->text() != "") ? (ui->resultDetailTable->item(row, 6)->text().toInt()) : -1;
        int selectedTarget = rowId % 4; // 获取当前选中的靶基因
        int selectedTarget2CurSeries = rowId/4; // 获取选中的靶基因是当前曲线的第几个

        if(rowId == -1){ // 行下标不合法或不存在
            return;
        }

        /* 取消曲线加粗 */
        if(this->targetLegendColor1 != "" && selectedTarget == 0){
            int lineFamAlpha = resFamSeriesList[selectedTarget2CurSeries]->color().alpha();
            QStringList tarColor1 = this->targetLegendColor1.split(",");
            resFamSeriesList[selectedTarget2CurSeries]->setPen(QPen(QColor(tarColor1[0].toInt(), tarColor1[1].toInt(), tarColor1[2].toInt(), lineFamAlpha),lineWidth,Qt::SolidLine)); //设置画笔
        }
        if(this->targetLegendColor2 != "" && selectedTarget == 1){
            int lineVicAlpha = resVicSeriesList[selectedTarget2CurSeries]->color().alpha();
            QStringList tarColor2 = this->targetLegendColor2.split(",");
            resVicSeriesList[selectedTarget2CurSeries]->setPen(QPen(QColor(tarColor2[0].toInt(), tarColor2[1].toInt(), tarColor2[2].toInt(), lineVicAlpha),lineWidth,Qt::SolidLine)); //设置画笔
        }
        if(this->targetLegendColor3 != "" && selectedTarget == 2){
            int lineRoxAlpha = resRoxSeriesList[selectedTarget2CurSeries]->color().alpha();
            QStringList tarColor3 = this->targetLegendColor3.split(",");
            resRoxSeriesList[selectedTarget2CurSeries]->setPen(QPen(QColor(tarColor3[0].toInt(), tarColor3[1].toInt(), tarColor3[2].toInt(), lineRoxAlpha),lineWidth,Qt::SolidLine)); //设置画笔
        }
        if(this->targetLegendColor4 != "" && selectedTarget == 3){
            int lineCy5Alpha = resCy5SeriesList[selectedTarget2CurSeries]->color().alpha();
            QStringList tarColor4 = this->targetLegendColor4.split(",");
            resCy5SeriesList[selectedTarget2CurSeries]->setPen(QPen(QColor(tarColor4[0].toInt(), tarColor4[1].toInt(), tarColor4[2].toInt(), lineCy5Alpha),lineWidth,Qt::SolidLine)); //设置画笔
        }
    }
}


void ExperimentResultUi::tableClick(QModelIndexList indexList){
    int l[8][12];
    for(int m = 0; m < 8; m ++){
        for(int n = 0; n < 12; n ++){
            l[m][n] = 0;
        }
    }

    foreach(QModelIndex index, indexList){
        l[index.row()][index.column()] = 1;
    }

    for(int i = 0; i < 8; i ++){
        for(int j = 0; j < 4; j ++){

            if(ui->resultTable->cellWidget(i, j)->children().length() <= 1){
                QWidget *la = ui->resultTable->cellWidget(i, j);
                QColor col;
                col.setRgb(229, 229, 229);
                QRgb rgbColor = qRgb(col.red(), col.green(), col.blue());
                QString mRgbStr = QString::number(rgbColor, 16);
                la->setStyleSheet("background-color: #" + mRgbStr);
            }


            if(l[i][j] == 1){
                //                if(ui->resultTable->cellWidget(i, j)->children().length() > 1){
                //                    QWidget *la = ui->resultTable->cellWidget(i, j);
                //                    QColor col;
                //                    col.setRgb(229, 229, 229);
                //                    QRgb rgbColor = qRgb(col.red(), col.green(), col.blue());
                //                    QString mRgbStr = QString::number(rgbColor, 16);
                //                    la->setStyleSheet("background-color: #" + mRgbStr);
                //                }

                if(ui->resultTable->cellWidget(i, j)->children().length() > 1 && reactionPlate.sampleList[j * 8 + i].color_value!= "null" && reactionPlate.sampleList[j * 8 + i].color_value!= ""){
                    QWidget *la = ui->resultTable->cellWidget(i, j);
                    QColor color = stringToColor(reactionPlate.sampleList[j * 8 + i].color_value);
                    QRgb rgbColor = qRgb(color.red(), color.green(), color.blue());
                    QString mRgbStr = QString::number(rgbColor, 16);
                    la->setStyleSheet("background-color: #" + mRgbStr);
                }else if(ui->resultTable->cellWidget(i, j)->children().length() > 1){
                    QWidget *la = ui->resultTable->cellWidget(i, j);
                    QColor col;
                    col.setRgb(255, 255, 255);
                    QRgb rgbColor = qRgb(col.red(), col.green(), col.blue());
                    QString mRgbStr = QString::number(rgbColor, 16);
                    la->setStyleSheet("background-color: #" + mRgbStr);
                }


            }
            else{
                //                if(ui->resultTable->cellWidget(i, j)->children().length() > 1 && reactionPlate.sampleList[j * 8 + i].color_value!= "null" && reactionPlate.sampleList[j * 8 + i].color_value!= ""){
                //                    QWidget *la = ui->resultTable->cellWidget(i, j);
                //                    QColor color = stringToColor(reactionPlate.sampleList[j * 8 + i].color_value);
                //                    QRgb rgbColor = qRgb(color.red(), color.green(), color.blue());
                //                    QString mRgbStr = QString::number(rgbColor, 16);
                //                    la->setStyleSheet("background-color: #" + mRgbStr);
                //                }else if(ui->resultTable->cellWidget(i, j)->children().length() > 1){
                //                    QWidget *la = ui->resultTable->cellWidget(i, j);
                //                    QColor col;
                //                    col.setRgb(255, 255, 255);
                //                    QRgb rgbColor = qRgb(col.red(), col.green(), col.blue());
                //                    QString mRgbStr = QString::number(rgbColor, 16);
                //                    la->setStyleSheet("background-color: #" + mRgbStr);
                //                }
                if(ui->resultTable->cellWidget(i, j)->children().length() > 1){
                    QWidget *la = ui->resultTable->cellWidget(i, j);
                    QColor col;
                    col.setRgb(229, 229, 229);
                    QRgb rgbColor = qRgb(col.red(), col.green(), col.blue());
                    QString mRgbStr = QString::number(rgbColor, 16);
                    la->setStyleSheet("background-color: #" + mRgbStr);
                }
            }

            //            LOG << ui->resultTable->cellWidget(i, j);
        }
    }

}

void ExperimentResultUi::updateTable(){
    for(int i = 0; i < 8; i ++){
        for(int j = 0; j < 12; j ++){
            QVBoxLayout* vLayout = new QVBoxLayout();
            QWidget* widgetLabel = new QWidget();
            QGridLayout* gLayout = new QGridLayout();
            widgetLabel->setLayout(vLayout);

            int count = 8 * j + i;
            if(ui->tableFilter->menu()->actions().value(0)->toolTip() == "样本名" && ui->tableFilter->menu()->actions().value(0)->isChecked() == true && ui->tableFilter->menu()->actions().value(2)->isChecked() == true){
                QString strname = reactionPlate.sampleList[count].name;
                if(strname != "null"){
                    QLabel *label = new QLabel();
                    //                    QColor color = stringToColor(reactionPlate.sampleList[count].color_value);
                    //                    QRgb rgbColor = qRgb(color.red(), color.green(), color.blue());
                    //                    QString mRgbStr = QString::number(rgbColor, 16);
                    QColor col;
                    col.setRgb(229, 229, 229);
                    QRgb rgbColor = qRgb(col.red(), col.green(), col.blue());
                    QString mRgbStr = QString::number(rgbColor, 16);
                    widgetLabel->setStyleSheet("background-color: #" + mRgbStr);
                    label->setText(strname);
                    QFont font;
                    font.setFamily("Alibaba PuHuiTi");
                    font.setPointSize(5);
                    label->setFont(font);
                    label->setAlignment(Qt::AlignHCenter | Qt::AlignVCenter);
                    //                    label->setFont(font);
                    label->setFixedHeight(8);
                    vLayout->addWidget(label);
                }
            }
            if(ui->tableFilter->menu()->actions().value(0)->toolTip() == "样本名" && ui->tableFilter->menu()->actions().value(0)->isChecked() == true && ui->tableFilter->menu()->actions().value(2)->isChecked() == false){
                QString name = reactionPlate.sampleList[count].name;
                if(name != "null"){
                    QLabel *label = new QLabel();
                    label->setText(name);
                    QFont font;
                    font.setFamily("Alibaba PuHuiTi");
                    font.setPointSize(5);
                    label->setFont(font);
                    label->setAlignment(Qt::AlignHCenter | Qt::AlignVCenter);
                    label->setFixedHeight(8);
                    vLayout->addWidget(label);
                }
            }
            if(ui->tableFilter->menu()->actions().value(0)->toolTip() == "样本名" && ui->tableFilter->menu()->actions().value(0)->isChecked() == false && ui->tableFilter->menu()->actions().value(2)->isChecked() == true){
                QString name = reactionPlate.sampleList[count].name;
                if(name != "null"){
                    QLabel *label = new QLabel();
                    //                    QColor color = stringToColor(reactionPlate.sampleList[count].color_value);
                    //                    QRgb rgbColor = qRgb(color.red(), color.green(), color.blue());
                    //                    QString mRgbStr = QString::number(rgbColor, 16);
                    QColor col;
                    col.setRgb(229, 229, 229);
                    QRgb rgbColor = qRgb(col.red(), col.green(), col.blue());
                    QString mRgbStr = QString::number(rgbColor, 16);
                    widgetLabel->setStyleSheet("background-color: #" + mRgbStr);
                    vLayout->addWidget(label);
                }
            }

            int p = 0;
            for(int l = 0; l < 20; l ++){
                if(ui->tableFilter->menu()->actions().value(1)->toolTip() == "靶基因" && ui->tableFilter->menu()->actions().value(1)->isChecked() == true){
                    if(reactionPlate.targetList[count][l].reporter != "null"){
                        QString reporter = reactionPlate.targetList[count][l].type;
                        if(reporter.contains("unknown(未知)")
                                || reporter.contains("Unknown(未知)")
                                || reporter.contains("未知")){reporter = "U " + reactionPlate.targetList[count][l].reporter;}
                        if(reporter.contains("stander(标准)")
                                || reporter.contains("Stander(标准)")
                                || reporter.contains("标准")){reporter = "S " + reactionPlate.targetList[count][l].reporter;}
                        if(reporter == "NTC"){reporter = "N " + reactionPlate.targetList[count][l].reporter;}
                        QLabel *label = new QLabel();
                        QColor color = stringToColor(reactionPlate.targetList[count][l].color);
                        QRgb rgbColor = qRgb(color.red(), color.green(), color.blue());
                        QString mRgbStr = QString::number(rgbColor, 16);
                        label->setText(reporter);
                        QFont font;
                        font.setFamily("Alibaba PuHuiTi");
                        font.setPointSize(5);
                        label->setFont(font);
                        label->setAlignment(Qt::AlignHCenter | Qt::AlignVCenter);
                        label->setStyleSheet("QLabel{border:2px solid #" + mRgbStr +";}");
                        //                        label->setFixedSize(55, 20);
                        label->resize(static_cast<int>(strlen(reinterpret_cast<char*>(label->text().data()))) * label->font().pointSize(),14);
                        label->setFixedHeight(12);
                        gLayout->addWidget(label, p / 10, p % 10, Qt::AlignCenter);
                        gLayout->setSpacing(0);
                        p ++;
                    }
                }
            }
            vLayout->setMargin(0);
            vLayout->setSpacing(0);
            vLayout->addLayout(gLayout);
            ui->resultTable->setCellWidget(i, j, widgetLabel);

            QWidget *la = ui->resultTable->cellWidget(i, j);
            QColor col;
            col.setRgb(229, 229, 229);
            QRgb rgbColor = qRgb(col.red(), col.green(), col.blue());
            QString mRgbStr = QString::number(rgbColor, 16);
            la->setStyleSheet("background-color: #" + mRgbStr);
        }

    }
}

QColor ExperimentResultUi::stringToColor(QString colorStr)
{
    QColor color;
    QStringList rgb=colorStr.split(',');
    if(rgb.size()==3){
        int r=rgb.at(0).toInt();
        int g=rgb.at(1).toInt();
        int b=rgb.at(2).toInt();
        color.setRgb(r,g,b);
    }
    else
        color.setNamedColor(colorStr);

    return color;
}

void ExperimentResultUi::ShowTooltip(QModelIndex index)
{
    normalIndex = index;
    int count = 8 * index.column() + index.row();
    QList<QLabel*> labels = ui->resultTable->cellWidget(index.row(), index.column())->findChildren<QLabel*>();

    QString data = "";
    for(int l = 0; l < 20; l ++){
        if(reactionPlate.targetList[count][l].name != "null"){
            data += reactionPlate.targetList[count][l].name;
            data += " ";
        }
    }

    QToolTip::showText(QCursor::pos(), data);

    for(int l = 0 ; l < labels.count(); l ++){
        labels.at(l)->setToolTip(data);
    }
    if(labels.size() != 0){
        /* 容器元素也加上toolTip */
        ui->resultTable->cellWidget(index.row(), index.column())->setToolTip(data);
    }
}

/* 休眠函数 */
void ExperimentResultUi::sleep(int msec){
    QTime dieTime = QTime::currentTime().addMSecs(msec);
    while( QTime::currentTime() < dieTime )
        QCoreApplication::processEvents(QEventLoop::AllEvents, 100);
}

